use crate::jj::parser::{Parser, parse_evolog};
use crate::model::{ChangeId, CommitId, CompareInfo, CompareRevisionInfo, Notification};
use crate::ui::views::{BlameView, DiffView, EvologView, ResolveView};
use super::state::{App, View};
impl App {
pub(crate) fn open_diff(&mut self, revision: &str) {
match self.jj.show(revision) {
Ok(content) => {
self.diff_view = Some(DiffView::new(revision.to_string(), content));
self.go_to_view(View::Diff);
self.error_message = None;
}
Err(e) => {
self.set_error(format!("Failed to load diff: {}", e));
}
}
}
pub(crate) fn open_diff_at_file(&mut self, revision: &str, file_path: &str) {
match self.jj.show(revision) {
Ok(content) => {
let mut diff_view = DiffView::new(revision.to_string(), content);
diff_view.jump_to_file(file_path);
self.diff_view = Some(diff_view);
self.go_to_view(View::Diff);
self.error_message = None;
}
Err(e) => {
self.set_error(format!("Failed to load diff: {}", e));
}
}
}
pub(crate) fn open_blame(&mut self, file_path: &str, revision: Option<&str>) {
match self.jj.file_annotate(file_path, revision) {
Ok(content) => {
let mut blame_view = BlameView::new();
blame_view.set_content(content, revision.map(|s| s.to_string()));
self.blame_view = Some(blame_view);
self.go_to_view(View::Blame);
self.error_message = None;
}
Err(e) => {
self.set_error(format!("Failed to load blame: {}", e));
}
}
}
pub(crate) fn open_compare_diff(&mut self, from: &str, to: &str) {
let diff_output = match self.jj.diff_range(from, to) {
Ok(output) => output,
Err(e) => {
self.set_error(format!("Failed to load diff: {}", e));
return;
}
};
let (from_result, to_result) = std::thread::scope(|s| {
let from_handle = s.spawn(|| self.jj.get_change_info(from));
let to_handle = s.spawn(|| self.jj.get_change_info(to));
(from_handle.join().unwrap(), to_handle.join().unwrap())
});
let from_info = match from_result {
Ok((change_id, bookmarks, author, timestamp, description)) => CompareRevisionInfo {
change_id: ChangeId::new(change_id),
commit_id: CommitId::new(from.to_string()),
bookmarks,
author,
timestamp,
description,
},
Err(e) => {
self.set_error(format!("Failed to load from revision: {}", e));
return;
}
};
let to_info = match to_result {
Ok((change_id, bookmarks, author, timestamp, description)) => CompareRevisionInfo {
change_id: ChangeId::new(change_id),
commit_id: CommitId::new(to.to_string()),
bookmarks,
author,
timestamp,
description,
},
Err(e) => {
self.set_error(format!("Failed to load to revision: {}", e));
return;
}
};
let content = Parser::parse_diff_body(&diff_output);
let compare_info = CompareInfo {
from: from_info,
to: to_info,
};
let diff_view = DiffView::new_compare(content, compare_info);
self.diff_view = Some(diff_view);
self.go_to_view(View::Diff);
self.error_message = None;
}
pub(crate) fn open_operation_history(&mut self) {
self.go_to_view(View::Operation);
}
pub(crate) fn open_evolog(&mut self, revision: &str) {
match self.jj.evolog(revision) {
Ok(output) => {
let entries = parse_evolog(&output);
if entries.is_empty() {
self.notification =
Some(Notification::info("No evolution history for this change"));
} else {
self.evolog_view = Some(EvologView::new(revision.to_string(), entries));
self.go_to_view(View::Evolog);
}
}
Err(e) => {
self.set_error(format!("Failed to load evolog: {}", e));
}
}
}
pub(crate) fn open_resolve_view(&mut self, revision: &str, is_working_copy: bool) {
match self.jj.resolve_list(Some(revision)) {
Ok(files) => {
if files.is_empty() {
self.notify_info("No conflicts in this change");
} else {
self.resolve_view = Some(ResolveView::new(
revision.to_string(),
is_working_copy,
files,
));
self.go_to_view(View::Resolve);
}
}
Err(e) => {
self.set_error(format!("Failed to list conflicts: {}", e));
}
}
}
}