git_contribution_analyzer/
app.rs1use crate::git::Contribution;
2use std::collections::HashMap;
3
4#[derive(PartialEq)]
5pub enum AppState {
6 Loading,
7 Main,
8}
9
10pub struct App {
11 pub state: AppState,
12 pub repositories: Vec<String>,
13 pub contributions: HashMap<String, Vec<Contribution>>,
14 pub author_summaries: Vec<AuthorSummary>,
15 pub current_tab: usize,
16 pub selected_in_tab: Vec<Option<usize>>,
17 pub loading_message: String,
18 pub loading_progress: u8,
19 pub show_help: bool,
20 pub quit: bool,
21}
22
23#[derive(Debug, Clone)]
24pub struct AuthorSummary {
25 pub author: String,
26 pub email: String,
27 pub total_commits: u32,
28 pub total_lines_added: u32,
29 pub total_lines_deleted: u32,
30 pub overall_contribution_percent: f64,
31 pub preferred_repo: String,
32 pub preferred_repo_percent: f64,
33}
34
35impl App {
36 pub fn new() -> App {
37 App {
38 state: AppState::Loading,
39 repositories: Vec::new(),
40 contributions: HashMap::new(),
41 author_summaries: Vec::new(),
42 current_tab: 0,
43 selected_in_tab: Vec::new(),
44 loading_message: String::from("Initializing..."),
45 loading_progress: 0,
46 show_help: false,
47 quit: false,
48 }
49 }
50
51 pub fn next(&mut self) {
52 if self.current_tab >= self.repositories.len() {
53 if let Some(i) = self.selected_in_tab[self.current_tab] {
54 if i >= self.author_summaries.len() - 1 {
55 self.selected_in_tab[self.current_tab] = Some(0);
56 } else {
57 self.selected_in_tab[self.current_tab] = Some(i + 1);
58 }
59 } else if !self.author_summaries.is_empty() {
60 self.selected_in_tab[self.current_tab] = Some(0);
61 }
62 } else {
63 if let Some(i) = self.selected_in_tab[self.current_tab] {
64 let repo_name = &self.repositories[self.current_tab];
65 if let Some(repo_contribs) = self.contributions.get(repo_name) {
66 if i >= repo_contribs.len() - 1 {
67 self.selected_in_tab[self.current_tab] = Some(0);
68 } else {
69 self.selected_in_tab[self.current_tab] = Some(i + 1);
70 }
71 }
72 } else {
73 let repo_name = &self.repositories[self.current_tab];
74 if let Some(repo_contribs) = self.contributions.get(repo_name) {
75 if !repo_contribs.is_empty() {
76 self.selected_in_tab[self.current_tab] = Some(0);
77 }
78 }
79 }
80 }
81 }
82
83 pub fn previous(&mut self) {
84 if self.current_tab >= self.repositories.len() {
85 if let Some(i) = self.selected_in_tab[self.current_tab] {
86 if i == 0 {
87 self.selected_in_tab[self.current_tab] = Some(self.author_summaries.len() - 1);
88 } else {
89 self.selected_in_tab[self.current_tab] = Some(i - 1);
90 }
91 } else if !self.author_summaries.is_empty() {
92 self.selected_in_tab[self.current_tab] = Some(self.author_summaries.len() - 1);
93 }
94 } else {
95 if let Some(i) = self.selected_in_tab[self.current_tab] {
96 let repo_name = &self.repositories[self.current_tab];
97 if let Some(repo_contribs) = self.contributions.get(repo_name) {
98 if i == 0 {
99 self.selected_in_tab[self.current_tab] = Some(repo_contribs.len() - 1);
100 } else {
101 self.selected_in_tab[self.current_tab] = Some(i - 1);
102 }
103 }
104 } else {
105 let repo_name = &self.repositories[self.current_tab];
106 if let Some(repo_contribs) = self.contributions.get(repo_name) {
107 if !repo_contribs.is_empty() {
108 self.selected_in_tab[self.current_tab] = Some(repo_contribs.len() - 1);
109 }
110 }
111 }
112 }
113 }
114
115 pub fn next_tab(&mut self) {
116 let tab_count = self.repositories.len() + 1;
117 self.current_tab = (self.current_tab + 1) % tab_count;
118 }
119
120 pub fn previous_tab(&mut self) {
121 let tab_count = self.repositories.len() + 1;
122 self.current_tab = (self.current_tab + tab_count - 1) % tab_count;
123 }
124
125 pub fn toggle_help(&mut self) {
126 self.show_help = !self.show_help;
127 }
128}