@@ -11,14 +11,17 @@ use crate::{
11
11
AsyncAppNotification , AsyncNotification ,
12
12
} ;
13
13
use anyhow:: Result ;
14
- use asyncgit:: sync:: {
15
- self , get_commit_info, CommitId , CommitInfo , RepoPathRef ,
16
- TreeFile ,
14
+ use asyncgit:: {
15
+ asyncjob:: AsyncSingleJob ,
16
+ sync:: {
17
+ get_commit_info, CommitId , CommitInfo , RepoPathRef , TreeFile ,
18
+ } ,
19
+ AsyncGitNotification , AsyncTreeFilesJob ,
17
20
} ;
18
21
use crossbeam_channel:: Sender ;
19
22
use crossterm:: event:: Event ;
20
23
use filetreelist:: { FileTree , FileTreeItem } ;
21
- use std:: fmt:: Write ;
24
+ use std:: { borrow :: Cow , fmt:: Write } ;
22
25
use std:: {
23
26
collections:: BTreeSet ,
24
27
convert:: From ,
@@ -44,7 +47,8 @@ pub struct RevisionFilesComponent {
44
47
queue : Queue ,
45
48
theme : SharedTheme ,
46
49
//TODO: store TreeFiles in `tree`
47
- files : Vec < TreeFile > ,
50
+ files : Option < Vec < TreeFile > > ,
51
+ async_treefiles : AsyncSingleJob < AsyncTreeFilesJob > ,
48
52
current_file : SyntaxTextComponent ,
49
53
tree : FileTree ,
50
54
scroll : VerticalScroll ,
@@ -60,6 +64,7 @@ impl RevisionFilesComponent {
60
64
repo : RepoPathRef ,
61
65
queue : & Queue ,
62
66
sender : & Sender < AsyncAppNotification > ,
67
+ sender_git : Sender < AsyncGitNotification > ,
63
68
theme : SharedTheme ,
64
69
key_config : SharedKeyConfig ,
65
70
) -> Self {
@@ -73,8 +78,9 @@ impl RevisionFilesComponent {
73
78
key_config. clone ( ) ,
74
79
theme. clone ( ) ,
75
80
) ,
81
+ async_treefiles : AsyncSingleJob :: new ( sender_git) ,
76
82
theme,
77
- files : Vec :: new ( ) ,
83
+ files : None ,
78
84
revision : None ,
79
85
focus : Focus :: Tree ,
80
86
key_config,
@@ -89,13 +95,15 @@ impl RevisionFilesComponent {
89
95
90
96
let same_id =
91
97
self . revision . as_ref ( ) . map_or ( false , |c| c. id == commit) ;
98
+
92
99
if !same_id {
93
- self . files =
94
- sync:: tree_files ( & self . repo . borrow ( ) , commit) ?;
95
- let filenames: Vec < & Path > =
96
- self . files . iter ( ) . map ( |f| f. path . as_path ( ) ) . collect ( ) ;
97
- self . tree = FileTree :: new ( & filenames, & BTreeSet :: new ( ) ) ?;
98
- self . tree . collapse_but_root ( ) ;
100
+ self . files = None ;
101
+
102
+ self . async_treefiles . spawn ( AsyncTreeFilesJob :: new (
103
+ self . repo . borrow ( ) . clone ( ) ,
104
+ commit,
105
+ ) ) ;
106
+
99
107
self . revision =
100
108
Some ( get_commit_info ( & self . repo . borrow ( ) , & commit) ?) ;
101
109
}
@@ -114,13 +122,35 @@ impl RevisionFilesComponent {
114
122
}
115
123
116
124
///
117
- pub fn update ( & mut self , ev : AsyncNotification ) {
125
+ pub fn update ( & mut self , ev : AsyncNotification ) -> Result < ( ) > {
118
126
self . current_file . update ( ev) ;
127
+
128
+ if matches ! (
129
+ ev,
130
+ AsyncNotification :: Git ( AsyncGitNotification :: TreeFiles )
131
+ ) {
132
+ if let Some ( last) = self . async_treefiles . take_last ( ) {
133
+ if let Some ( Ok ( last) ) = last. result ( ) {
134
+ let filenames: Vec < & Path > = last
135
+ . iter ( )
136
+ . map ( |f| f. path . as_path ( ) )
137
+ . collect ( ) ;
138
+ self . tree =
139
+ FileTree :: new ( & filenames, & BTreeSet :: new ( ) ) ?;
140
+ self . tree . collapse_but_root ( ) ;
141
+
142
+ self . files = Some ( last) ;
143
+ }
144
+ }
145
+ }
146
+
147
+ Ok ( ( ) )
119
148
}
120
149
121
150
///
122
151
pub fn any_work_pending ( & self ) -> bool {
123
152
self . current_file . any_work_pending ( )
153
+ || self . async_treefiles . is_pending ( )
124
154
}
125
155
126
156
fn tree_item_to_span < ' a > (
@@ -190,8 +220,9 @@ impl RevisionFilesComponent {
190
220
}
191
221
192
222
fn open_finder ( & self ) {
193
- self . queue
194
- . push ( InternalEvent :: OpenFileFinder ( self . files . clone ( ) ) ) ;
223
+ self . queue . push ( InternalEvent :: OpenFileFinder (
224
+ self . files . clone ( ) . unwrap_or_default ( ) ,
225
+ ) ) ;
195
226
}
196
227
197
228
pub fn find_file ( & mut self , file : & Option < PathBuf > ) {
@@ -221,18 +252,20 @@ impl RevisionFilesComponent {
221
252
fn selection_changed ( & mut self ) {
222
253
//TODO: retrieve TreeFile from tree datastructure
223
254
if let Some ( file) = self . selected_file_path_with_prefix ( ) {
224
- let path = Path :: new ( & file) ;
225
- if let Some ( item) =
226
- self . files . iter ( ) . find ( |f| f. path == path)
227
- {
228
- if let Ok ( path) = path. strip_prefix ( "./" ) {
229
- return self . current_file . load_file (
230
- path. to_string_lossy ( ) . to_string ( ) ,
231
- item,
232
- ) ;
255
+ if let Some ( files) = & self . files {
256
+ let path = Path :: new ( & file) ;
257
+ if let Some ( item) =
258
+ files. iter ( ) . find ( |f| f. path == path)
259
+ {
260
+ if let Ok ( path) = path. strip_prefix ( "./" ) {
261
+ return self . current_file . load_file (
262
+ path. to_string_lossy ( ) . to_string ( ) ,
263
+ item,
264
+ ) ;
265
+ }
233
266
}
267
+ self . current_file . clear ( ) ;
234
268
}
235
- self . current_file . clear ( ) ;
236
269
}
237
270
}
238
271
@@ -268,18 +301,30 @@ impl RevisionFilesComponent {
268
301
let is_tree_focused = matches ! ( self . focus, Focus :: Tree ) ;
269
302
270
303
let title = self . title_within ( tree_width) ;
271
- ui:: draw_list_block (
272
- f,
273
- area,
274
- Block :: default ( )
275
- . title ( Span :: styled (
276
- title,
277
- self . theme . title ( is_tree_focused) ,
278
- ) )
279
- . borders ( Borders :: ALL )
280
- . border_style ( self . theme . block ( is_tree_focused) ) ,
281
- items,
282
- ) ;
304
+ let block = Block :: default ( )
305
+ . title ( Span :: styled (
306
+ title,
307
+ self . theme . title ( is_tree_focused) ,
308
+ ) )
309
+ . borders ( Borders :: ALL )
310
+ . border_style ( self . theme . block ( is_tree_focused) ) ;
311
+
312
+ if self . files . is_some ( ) {
313
+ ui:: draw_list_block ( f, area, block, items) ;
314
+ } else {
315
+ ui:: draw_list_block (
316
+ f,
317
+ area,
318
+ block,
319
+ vec ! [ Span :: styled(
320
+ Cow :: from( strings:: loading_text(
321
+ & self . key_config,
322
+ ) ) ,
323
+ self . theme. text( false , false ) ,
324
+ ) ]
325
+ . into_iter ( ) ,
326
+ ) ;
327
+ }
283
328
284
329
if is_tree_focused {
285
330
self . scroll . draw ( f, area, & self . theme ) ;
0 commit comments