@@ -5,7 +5,7 @@ use std::time::Instant;
55use ratatui:: widgets:: TableState ;
66
77use crate :: discovery:: RepoRef ;
8- use crate :: status:: RepoState ;
8+ use crate :: status:: { parse_ahead_behind , RepoState , NO_REMOTE } ;
99use crate :: worker:: { Action , WorkerCmd } ;
1010
1111#[ derive( Clone , Copy , PartialEq ) ]
@@ -17,11 +17,9 @@ pub enum SortOrder {
1717}
1818
1919#[ derive( Clone , Copy , PartialEq ) ]
20- #[ allow( dead_code) ]
2120pub enum StatusType {
2221 Success ,
2322 Error ,
24- Warning ,
2523 Info ,
2624}
2725
@@ -69,9 +67,12 @@ impl App {
6967 pub fn request_scan ( & mut self ) {
7068 self . loading = true ;
7169 self . scan_progress = 0.0 ;
72- let _ = self . cmd_tx . send ( WorkerCmd :: Scan {
70+ if let Err ( err ) = self . cmd_tx . send ( WorkerCmd :: Scan {
7371 root : self . root . clone ( ) ,
74- } ) ;
72+ } ) {
73+ self . loading = false ;
74+ self . set_status ( format ! ( "Worker unavailable: {err}" ) ) ;
75+ }
7576 }
7677
7778 pub fn request_refresh ( & mut self ) {
@@ -83,7 +84,9 @@ impl App {
8384 git_dir : repo. git_dir . clone ( ) ,
8485 } )
8586 . collect ( ) ;
86- let _ = self . cmd_tx . send ( WorkerCmd :: Refresh { repos } ) ;
87+ if let Err ( err) = self . cmd_tx . send ( WorkerCmd :: Refresh { repos } ) {
88+ self . set_status ( format ! ( "Worker unavailable: {err}" ) ) ;
89+ }
8790 }
8891
8992 pub fn request_confirm ( & mut self , action : Action ) {
@@ -94,7 +97,7 @@ impl App {
9497
9598 // Validate that we have a remote before allowing push/pull
9699 if let Some ( repo) = self . selected_repo ( ) {
97- if repo. remote_url == "-" {
100+ if repo. remote_url == NO_REMOTE {
98101 self . set_status ( "No remote configured for this repository" . to_string ( ) ) ;
99102 return ;
100103 }
@@ -105,20 +108,25 @@ impl App {
105108
106109 pub fn perform_action ( & mut self , action : Action ) {
107110 if let Some ( repo) = self . selected_repo ( ) {
108- let _ = self . cmd_tx . send ( WorkerCmd :: Action {
111+ if let Err ( err ) = self . cmd_tx . send ( WorkerCmd :: Action {
109112 path : repo. path . clone ( ) ,
110113 action,
111- } ) ;
112- self . set_status ( "Running action..." . to_string ( ) ) ;
114+ } ) {
115+ self . set_status ( format ! ( "Worker unavailable: {err}" ) ) ;
116+ } else {
117+ self . set_status ( "Running action..." . to_string ( ) ) ;
118+ }
113119 }
114120 }
115121
116122 pub fn request_quit ( & mut self ) {
117- let _ = self . cmd_tx . send ( WorkerCmd :: Quit ) ;
123+ if let Err ( err) = self . cmd_tx . send ( WorkerCmd :: Quit ) {
124+ self . set_status ( format ! ( "Worker unavailable: {err}" ) ) ;
125+ }
118126 }
119127
120128 pub fn next ( & mut self ) {
121- let len = self . filtered_repos ( ) . len ( ) ;
129+ let len = self . filtered_indices ( ) . len ( ) ;
122130 if len == 0 {
123131 return ;
124132 }
@@ -130,7 +138,7 @@ impl App {
130138 }
131139
132140 pub fn previous ( & mut self ) {
133- let len = self . filtered_repos ( ) . len ( ) ;
141+ let len = self . filtered_indices ( ) . len ( ) ;
134142 if len == 0 {
135143 return ;
136144 }
@@ -148,7 +156,7 @@ impl App {
148156 }
149157
150158 pub fn page_down ( & mut self ) {
151- let len = self . filtered_repos ( ) . len ( ) ;
159+ let len = self . filtered_indices ( ) . len ( ) ;
152160 if len == 0 {
153161 return ;
154162 }
@@ -160,7 +168,7 @@ impl App {
160168 }
161169
162170 pub fn page_up ( & mut self ) {
163- let len = self . filtered_repos ( ) . len ( ) ;
171+ let len = self . filtered_indices ( ) . len ( ) ;
164172 if len == 0 {
165173 return ;
166174 }
@@ -172,25 +180,24 @@ impl App {
172180 }
173181
174182 pub fn jump_to_first ( & mut self ) {
175- if !self . filtered_repos ( ) . is_empty ( ) {
183+ if !self . filtered_indices ( ) . is_empty ( ) {
176184 self . table_state . select ( Some ( 0 ) ) ;
177185 }
178186 }
179187
180188 pub fn jump_to_last ( & mut self ) {
181- let len = self . filtered_repos ( ) . len ( ) ;
189+ let len = self . filtered_indices ( ) . len ( ) ;
182190 if len > 0 {
183191 self . table_state . select ( Some ( len - 1 ) ) ;
184192 }
185193 }
186194
187195 pub fn selected_repo ( & self ) -> Option < & RepoState > {
188- let filtered = self . filtered_repos ( ) ;
189- self . table_state . selected ( ) . and_then ( |i| {
190- filtered
191- . get ( i)
192- . and_then ( |r| self . repos . iter ( ) . find ( |repo| repo. path == r. path ) )
193- } )
196+ let indices = self . filtered_indices ( ) ;
197+ self . table_state
198+ . selected ( )
199+ . and_then ( |i| indices. get ( i) . copied ( ) )
200+ . and_then ( |repo_idx| self . repos . get ( repo_idx) )
194201 }
195202
196203 pub fn set_status ( & mut self , status : String ) {
@@ -261,17 +268,18 @@ impl App {
261268 self . help_visible = !self . help_visible ;
262269 }
263270
264- pub fn filtered_repos ( & self ) -> Vec < RepoState > {
271+ pub fn filtered_indices ( & self ) -> Vec < usize > {
265272 if self . search_query . is_empty ( ) {
266- self . repos . clone ( )
267- } else {
268- let query_lower = self . search_query . to_lowercase ( ) ;
269- self . repos
270- . iter ( )
271- . filter ( |repo| repo. name . to_lowercase ( ) . contains ( & query_lower) )
272- . cloned ( )
273- . collect ( )
273+ return ( 0 ..self . repos . len ( ) ) . collect ( ) ;
274274 }
275+
276+ let query_lower = self . search_query . to_lowercase ( ) ;
277+ self . repos
278+ . iter ( )
279+ . enumerate ( )
280+ . filter ( |( _, repo) | repo. name . to_lowercase ( ) . contains ( & query_lower) )
281+ . map ( |( idx, _) | idx)
282+ . collect ( )
275283 }
276284
277285 pub fn enter_search_mode ( & mut self ) {
@@ -304,20 +312,8 @@ impl App {
304312}
305313
306314fn has_ahead_or_behind ( value : & str ) -> bool {
307- if value == "-" {
308- return false ;
315+ match parse_ahead_behind ( value) {
316+ Some ( ( ahead, behind) ) => ahead > 0 || behind > 0 ,
317+ None => false ,
309318 }
310-
311- let Some ( ( ahead_part, behind_part) ) = value. split_once ( '/' ) else {
312- return false ;
313- } ;
314-
315- let Ok ( ahead) = ahead_part. trim_start_matches ( '+' ) . parse :: < u32 > ( ) else {
316- return false ;
317- } ;
318- let Ok ( behind) = behind_part. trim_start_matches ( '-' ) . parse :: < u32 > ( ) else {
319- return false ;
320- } ;
321-
322- ahead > 0 || behind > 0
323319}
0 commit comments