Skip to content

Commit

Permalink
refactor: simplify the code
Browse files Browse the repository at this point in the history
  • Loading branch information
orhun committed Dec 13, 2024
1 parent 4fcc94f commit 0819daa
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 223 deletions.
53 changes: 20 additions & 33 deletions git-cliff-tui/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ pub enum Event {
/// Terminal resize.
Resize(u16, u16),
/// Generate changelog.
Generate,
/// Generate changelog when the file changes.
AutoGenerate,
Generate(bool),
/// Quit the application.
Quit,
}

/// Terminal event handler.
#[allow(dead_code)]
#[derive(Debug)]
pub struct EventHandler {
/// Event sender channel.
pub sender: mpsc::Sender<Event>,
pub sender: mpsc::Sender<Event>,
/// Event receiver channel.
receiver: mpsc::Receiver<Event>,
pub receiver: mpsc::Receiver<Event>,
/// Event handler thread.
handler: thread::JoinHandle<()>,
handler: thread::JoinHandle<()>,
}

impl EventHandler {
Expand Down Expand Up @@ -95,14 +95,6 @@ impl EventHandler {
handler,
}
}

/// Receive the next event from the handler thread.
///
/// This function will always block the current thread if
/// there is no data available and it's possible for more data to be sent.
pub fn next(&self) -> Result<Event> {
Ok(self.receiver.recv()?)
}
}

/// Handles the key events and updates the state of [`State`].
Expand All @@ -113,48 +105,43 @@ pub fn handle_key_events(
) -> Result<()> {
match key_event.code {
KeyCode::Esc | KeyCode::Char('q') => {
state.quit();
sender.send(Event::Quit)?;
}
KeyCode::Char('c') | KeyCode::Char('C') => {
if key_event.modifiers == KeyModifiers::CONTROL {
state.quit();
} else if let Some(contents) = state.generate_changelog()? {
sender.send(Event::Quit)?;
} else {
if let Some(clipboard) = &mut state.clipboard {
if let Err(e) = clipboard.set_contents(contents) {
eprintln!("Failed to set clipboard contents: {e}");
if let Err(e) = clipboard.set_contents(state.contents.clone()) {
return Err(format!(
"Failed to set clipboard contents: {e}"
)
.into());
}
}
}
}
KeyCode::Char('k') | KeyCode::Char('K') | KeyCode::Up => {
state.list_state.select_previous();
sender.send(Event::Generate)?;
sender.send(Event::Generate(false))?;
}
KeyCode::Char('j') | KeyCode::Char('J') | KeyCode::Down => {
state.list_state.select_next();
sender.send(Event::Generate)?;
sender.send(Event::Generate(false))?;
}
KeyCode::Char('h') | KeyCode::Char('H') | KeyCode::Left => {
state.scroll_index = state.scroll_index.saturating_sub(1);
}
KeyCode::Char('l') | KeyCode::Char('L') | KeyCode::Right => {
state.scroll_index = state.scroll_index.saturating_add(1);

// TODO: Tweak latest flag
//
// state.args.latest = !state.args.latest;
// sender.send(Event::Generate)?;
}
KeyCode::Enter => sender.send(Event::Generate)?,
KeyCode::Char('a') | KeyCode::Char('A') => {
state.autoload = !state.autoload;
}
KeyCode::Char('t') | KeyCode::Char('T') => {
state.is_toggled = !state.is_toggled;
state.args.latest = !state.args.latest;
sender.send(Event::Generate(true))?;
}
KeyCode::Enter => sender.send(Event::Generate(false))?,
KeyCode::Char('u') | KeyCode::Char('U') => {
state.args.unreleased = !state.args.unreleased;
sender.send(Event::Generate)?;
sender.send(Event::Generate(true))?;
}
_ => {}
}
Expand Down
51 changes: 5 additions & 46 deletions git-cliff-tui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,14 @@ fn main() -> Result<()> {
// Create an application state.
let mut state = State::new(args.clone())?;

// Get the changelog data.
state.get_changelog_data()?;

// Initialize the terminal user interface.
let events = EventHandler::new(250);
let mut terminal = ratatui::init();

// TODO: Watch for file changes.
//
// let sender = events.sender.clone();
// let mut watcher =
// notify::recommended_watcher(move |res: notify::Result<notify::Event>| {
// match res {
// Ok(event) => {
// if event.kind.is_modify() {
// sender
// .send(Event::AutoGenerate)
// .expect("failed to send event");
// }
// }
// Err(e) => panic!("watch error: {e:?}"),
// }
// })?;

// Start the main loop.
while state.is_running {
loop {
terminal.draw(|frame| ui::render(&mut state, frame))?;
let event = events.next()?;
let event = events.receiver.recv()?;
match event {
Event::Tick => state.tick(),
Event::Key(key_event) => event::handle_key_events(
Expand All @@ -62,31 +42,10 @@ fn main() -> Result<()> {
)?,
Event::Mouse(_) => {}
Event::Resize(_, _) => {}
Event::Generate | Event::AutoGenerate => {
state.process_changelog()?;
// if event == Event::AutoGenerate && !state.autoload {
// continue;
// }
// let sender = events.sender.clone();
// let args = state.args.clone();
// state.is_generating = true;
// state.args.config = PathBuf::from(
// state.configs[state.list_state.selected().
// unwrap_or_default()] .file
// .clone(),
// );
// thread::spawn(move || {
// let mut output = Vec::new();
// sender
// .send(match git_cliff::run(args, &mut output) {
// Ok(()) => Event::RenderMarkdown(
// String::from_utf8_lossy(&output).to_string(),
// ),
// Err(e) => Event::Error(e.to_string()),
// })
// .expect("failed to send event");
// });
Event::Generate(update_data) => {
state.generate_changelog(update_data)?;
}
Event::Quit => break,
}
}

Expand Down
79 changes: 25 additions & 54 deletions git-cliff-tui/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct State<'a> {
/// The state of the list.
pub list_state: ListState,
/// Changelog object.
pub changelog: Option<Changelog<'a>>,
changelog: Changelog<'a>,
/// Changelog contents.
pub contents: String,
/// Scroll index.
Expand All @@ -29,27 +29,20 @@ pub struct State<'a> {
pub throbber_state: ThrobberState,
/// Is generating?
pub is_generating: bool,
/// Is the sidebar toggled?
pub is_toggled: bool,
/// Autoload changes.
pub autoload: bool,
/// Is the application running?
pub is_running: bool,
}

impl State<'_> {
/// Constructs a new instance.
pub fn new(args: Args) -> Result<Self> {
let configs = BuiltinConfig::iter().map(|file| file.to_string()).collect();
Ok(Self {
args,
builtin_configs: configs,
list_state: {
let mut list_state = ListState::default();
list_state.select_first();
list_state
},
changelog: None,
changelog: git_cliff::generate_changelog(&mut args.clone())?,
contents: String::new(),
scroll_index: 0,
throbber_state: ThrobberState::default(),
Expand All @@ -61,52 +54,35 @@ impl State<'_> {
}
},
is_generating: false,
is_toggled: true,
autoload: true,
is_running: true,
args,
})
}

/// Generates the changelog.
///
/// This runs once the application starts for fetching the remote data if
/// necessary.
pub fn get_changelog_data(&mut self) -> Result<()> {
self.changelog = Some(git_cliff::generate_changelog(&mut self.args)?);
Ok(())
}

/// Returns the changelog contents.
pub fn generate_changelog(&mut self) -> Result<Option<String>> {
if let Some(changelog) = &self.changelog {
let config = BuiltinConfig::parse(
self.builtin_configs[self.list_state.selected().unwrap_or_default()]
.clone(),
)?
.0;
let mut changelog =
Changelog::new(changelog.releases.clone(), config.clone())?;
changelog.add_remote_context()?;
let mut output = Vec::new();
git_cliff::write_changelog(
self.args.clone(),
changelog.clone(),
&mut output,
)?;
let contents = String::from_utf8(output)?;
self.changelog = Some(changelog);
Ok(Some(contents))
} else {
Ok(None)
}
}
pub fn generate_changelog(&mut self, update_data: bool) -> Result<String> {
let config = BuiltinConfig::parse(
self.builtin_configs[self.list_state.selected().unwrap_or_default()]
.clone(),
)?
.0;

/// Processes the changelog contents.
pub fn process_changelog(&mut self) -> Result<()> {
if let Some(contents) = &self.generate_changelog()? {
self.contents = contents.clone();
if update_data {
self.changelog = git_cliff::generate_changelog(&mut self.args.clone())?;
}
Ok(())
let mut changelog =
Changelog::new(self.changelog.releases.clone(), config.clone())?;
changelog.add_remote_context()?;
let mut output = Vec::new();
git_cliff::write_changelog(
self.args.clone(),
changelog.clone(),
&mut output,
)?;
let contents = String::from_utf8(output)?;

self.changelog = changelog;
self.contents = contents.clone();
Ok(contents)
}

/// Handles the tick event of the terminal.
Expand All @@ -115,9 +91,4 @@ impl State<'_> {
self.throbber_state.calc_next();
}
}

/// Set running to false to quit the application.
pub fn quit(&mut self) {
self.is_running = false;
}
}
Loading

0 comments on commit 0819daa

Please sign in to comment.