mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 08:58:21 +00:00
Merge 384d0abff7 into 8619c07f3f
This commit is contained in:
commit
c10ae8027c
3 changed files with 110 additions and 45 deletions
|
|
@ -437,6 +437,10 @@ impl App {
|
|||
self.select_branch_popup.update_git(ev)?;
|
||||
}
|
||||
|
||||
if let AsyncNotification::App(AsyncAppNotification::StashSaveDone) = ev {
|
||||
self.stashmsg_popup.on_stash_save_done();
|
||||
}
|
||||
|
||||
self.files_tab.update_async(ev)?;
|
||||
self.blame_file_popup.update_async(ev)?;
|
||||
self.revision_files_popup.update(ev)?;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ pub enum SyntaxHighlightProgress {
|
|||
pub enum AsyncAppNotification {
|
||||
///
|
||||
SyntaxHighlighting(SyntaxHighlightProgress),
|
||||
/// background stash in `StashMsgPopup` finished
|
||||
StashSaveDone,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -5,14 +5,22 @@ use crate::components::{
|
|||
use crate::{
|
||||
app::Environment,
|
||||
keys::{key_match, SharedKeyConfig},
|
||||
queue::{AppTabs, InternalEvent, Queue},
|
||||
queue::{AppTabs, InternalEvent, NeedsUpdate, Queue},
|
||||
strings,
|
||||
tabs::StashingOptions,
|
||||
AsyncAppNotification,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use asyncgit::sync::{self, RepoPathRef};
|
||||
use crossbeam_channel::Sender;
|
||||
use crossterm::event::Event;
|
||||
use ratatui::{layout::Rect, Frame};
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
thread,
|
||||
};
|
||||
|
||||
const STASHING_MSG: &str = "Stashing...";
|
||||
|
||||
pub struct StashMsgPopup {
|
||||
repo: RepoPathRef,
|
||||
|
|
@ -20,6 +28,9 @@ pub struct StashMsgPopup {
|
|||
input: TextInputComponent,
|
||||
queue: Queue,
|
||||
key_config: SharedKeyConfig,
|
||||
sender_app: Sender<AsyncAppNotification>,
|
||||
stashing: bool,
|
||||
stash_result: Arc<Mutex<Option<Result<(), String>>>>,
|
||||
}
|
||||
|
||||
impl DrawableComponent for StashMsgPopup {
|
||||
|
|
@ -39,13 +50,15 @@ impl Component for StashMsgPopup {
|
|||
if self.is_visible() || force_all {
|
||||
self.input.commands(out, force_all);
|
||||
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::stashing_confirm_msg(
|
||||
&self.key_config,
|
||||
),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
if !self.stashing {
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::stashing_confirm_msg(
|
||||
&self.key_config,
|
||||
),
|
||||
true,
|
||||
true,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
visibility_blocking(self)
|
||||
|
|
@ -53,51 +66,19 @@ impl Component for StashMsgPopup {
|
|||
|
||||
fn event(&mut self, ev: &Event) -> Result<EventState> {
|
||||
if self.is_visible() {
|
||||
if self.stashing {
|
||||
return Ok(EventState::Consumed);
|
||||
}
|
||||
|
||||
if self.input.event(ev)?.is_consumed() {
|
||||
return Ok(EventState::Consumed);
|
||||
}
|
||||
|
||||
if let Event::Key(e) = ev {
|
||||
if key_match(e, self.key_config.keys.enter) {
|
||||
let result = sync::stash_save(
|
||||
&self.repo.borrow(),
|
||||
if self.input.get_text().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.input.get_text())
|
||||
},
|
||||
self.options.stash_untracked,
|
||||
self.options.keep_index,
|
||||
);
|
||||
match result {
|
||||
Ok(_) => {
|
||||
self.input.clear();
|
||||
self.hide();
|
||||
|
||||
self.queue.push(
|
||||
InternalEvent::TabSwitch(
|
||||
AppTabs::Stashlist,
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
self.hide();
|
||||
log::error!(
|
||||
"e: {} (options: {:?})",
|
||||
e,
|
||||
self.options
|
||||
);
|
||||
self.queue.push(
|
||||
InternalEvent::ShowErrorMsg(format!(
|
||||
"stash error:\n{}\noptions:\n{:?}",
|
||||
e, self.options
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
self.start_stash_async()?;
|
||||
}
|
||||
|
||||
// stop key event propagation
|
||||
return Ok(EventState::Consumed);
|
||||
}
|
||||
}
|
||||
|
|
@ -110,9 +91,11 @@ impl Component for StashMsgPopup {
|
|||
|
||||
fn hide(&mut self) {
|
||||
self.input.hide();
|
||||
self.stashing = false;
|
||||
}
|
||||
|
||||
fn show(&mut self) -> Result<()> {
|
||||
self.stashing = false;
|
||||
self.input.show()?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -134,6 +117,9 @@ impl StashMsgPopup {
|
|||
.with_input_type(InputType::Singleline),
|
||||
key_config: env.key_config.clone(),
|
||||
repo: env.repo.clone(),
|
||||
sender_app: env.sender_app.clone(),
|
||||
stashing: false,
|
||||
stash_result: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,4 +127,77 @@ impl StashMsgPopup {
|
|||
pub const fn options(&mut self, options: StashingOptions) {
|
||||
self.options = options;
|
||||
}
|
||||
|
||||
///
|
||||
pub fn on_stash_save_done(&mut self) {
|
||||
if !self.stashing {
|
||||
return;
|
||||
}
|
||||
|
||||
let error = self
|
||||
.stash_result
|
||||
.lock()
|
||||
.ok()
|
||||
.and_then(|mut guard| guard.take())
|
||||
.and_then(Result::err);
|
||||
|
||||
self.complete_stash(error);
|
||||
}
|
||||
|
||||
fn complete_stash(&mut self, error: Option<String>) {
|
||||
self.stashing = false;
|
||||
|
||||
if let Some(msg) = error {
|
||||
self.hide();
|
||||
self.queue.push(InternalEvent::ShowErrorMsg(msg));
|
||||
} else {
|
||||
self.input.clear();
|
||||
self.hide();
|
||||
self.queue
|
||||
.push(InternalEvent::TabSwitch(AppTabs::Stashlist));
|
||||
self.queue.push(InternalEvent::Update(NeedsUpdate::ALL));
|
||||
}
|
||||
}
|
||||
|
||||
fn start_stash_async(&mut self) -> Result<()> {
|
||||
let repo_path = self.repo.borrow().clone();
|
||||
let message = if self.input.get_text().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.input.get_text().to_string())
|
||||
};
|
||||
|
||||
self.stashing = true;
|
||||
self.input.enabled(false);
|
||||
self.input.set_text(STASHING_MSG.into());
|
||||
|
||||
let options = self.options;
|
||||
let sender_app = self.sender_app.clone();
|
||||
let stash_result = Arc::clone(&self.stash_result);
|
||||
*stash_result.lock().map_err(|_| {
|
||||
anyhow::anyhow!("stash result lock poisoned")
|
||||
})? = None;
|
||||
|
||||
thread::spawn(move || {
|
||||
let result = sync::stash_save(
|
||||
&repo_path,
|
||||
message.as_deref(),
|
||||
options.stash_untracked,
|
||||
options.keep_index,
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"stash error:\n{e}\noptions:\n{options:?}",
|
||||
)
|
||||
});
|
||||
|
||||
if let Ok(mut guard) = stash_result.lock() {
|
||||
*guard = Some(result);
|
||||
}
|
||||
let _ = sender_app.send(AsyncAppNotification::StashSaveDone);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue