gitui 0.22.1

blazing fast terminal-ui for git
use super::{
	textinput::TextInputComponent, visibility_blocking,
	CommandBlocking, CommandInfo, Component, DrawableComponent,
	EventState,
};
use crate::{
	keys::{key_match, SharedKeyConfig},
	queue::{InternalEvent, NeedsUpdate, Queue},
	strings,
	ui::style::SharedTheme,
};
use anyhow::Result;
use asyncgit::sync::{self, RepoPathRef};
use crossterm::event::Event;
use tui::{backend::Backend, layout::Rect, Frame};

pub struct RenameBranchComponent {
	repo: RepoPathRef,
	input: TextInputComponent,
	branch_ref: Option<String>,
	queue: Queue,
	key_config: SharedKeyConfig,
}

impl DrawableComponent for RenameBranchComponent {
	fn draw<B: Backend>(
		&self,
		f: &mut Frame<B>,
		rect: Rect,
	) -> Result<()> {
		self.input.draw(f, rect)?;

		Ok(())
	}
}

impl Component for RenameBranchComponent {
	fn commands(
		&self,
		out: &mut Vec<CommandInfo>,
		force_all: bool,
	) -> CommandBlocking {
		if self.is_visible() || force_all {
			self.input.commands(out, force_all);

			out.push(CommandInfo::new(
				strings::commands::rename_branch_confirm_msg(
					&self.key_config,
				),
				true,
				true,
			));
		}

		visibility_blocking(self)
	}

	fn event(&mut self, ev: &Event) -> Result<EventState> {
		if self.is_visible() {
			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) {
					self.rename_branch();
				}

				return Ok(EventState::Consumed);
			}
		}
		Ok(EventState::NotConsumed)
	}

	fn is_visible(&self) -> bool {
		self.input.is_visible()
	}

	fn hide(&mut self) {
		self.input.hide();
	}

	fn show(&mut self) -> Result<()> {
		self.input.show()?;

		Ok(())
	}
}

impl RenameBranchComponent {
	///
	pub fn new(
		repo: RepoPathRef,
		queue: Queue,
		theme: SharedTheme,
		key_config: SharedKeyConfig,
	) -> Self {
		Self {
			repo,
			queue,
			input: TextInputComponent::new(
				theme,
				key_config.clone(),
				&strings::rename_branch_popup_title(&key_config),
				&strings::rename_branch_popup_msg(&key_config),
				true,
			),
			branch_ref: None,
			key_config,
		}
	}

	///
	pub fn open(
		&mut self,
		branch_ref: String,
		cur_name: String,
	) -> Result<()> {
		self.branch_ref = None;
		self.branch_ref = Some(branch_ref);
		self.input.set_text(cur_name);
		self.show()?;

		Ok(())
	}

	///
	pub fn rename_branch(&mut self) {
		if let Some(br) = &self.branch_ref {
			let res = sync::rename_branch(
				&self.repo.borrow(),
				br,
				self.input.get_text(),
			);

			match res {
				Ok(_) => {
					self.queue.push(InternalEvent::Update(
						NeedsUpdate::ALL,
					));
					self.hide();
					self.queue.push(InternalEvent::SelectBranch);
				}
				Err(e) => {
					log::error!("create branch: {}", e,);
					self.queue.push(InternalEvent::ShowErrorMsg(
						format!("rename branch error:\n{e}",),
					));
				}
			}
		} else {
			log::error!("create branch: No branch selected");
			self.queue.push(InternalEvent::ShowErrorMsg(
				"rename branch error: No branch selected to rename"
					.to_string(),
			));
		}

		self.input.clear();
	}
}