@@ -2,65 +2,34 @@ use std::{pin::Pin, time::Duration};
2
2
3
3
use crossterm:: event:: { Event as CrosstermEvent , KeyCode , KeyEvent , KeyEventKind } ;
4
4
use futures_util:: { FutureExt , Stream , StreamExt } ;
5
+ use ratatui:: widgets:: Widget ;
5
6
use tokio:: time:: { Instant , Sleep } ;
6
7
7
8
use crate :: {
8
9
auth:: {
9
10
self ,
10
11
device_flow:: { DeviceAccessTokenResponse , DeviceAuthorizationResponse } ,
11
- Authentication ,
12
+ Credential ,
12
13
} ,
13
14
client:: Client ,
14
15
command:: Command ,
15
16
job:: Jobs ,
16
17
terminal:: Terminal ,
17
18
ui:: {
18
19
self ,
19
- components:: {
20
- entries:: Entries ,
21
- login:: Login ,
22
- prompt:: Prompt ,
23
- subscription:: Subscription ,
24
- tabs:: { Tab , Tabs } ,
25
- Components ,
26
- } ,
20
+ components:: { authentication:: Authentication , root:: Root , tabs:: Tab , Components } ,
27
21
theme:: Theme ,
28
22
} ,
29
23
} ;
30
24
31
25
mod direction;
32
26
pub use direction:: { Direction , IndexOutOfRange } ;
33
27
34
- /// Cureent ui screen
35
- pub enum Screen {
36
- Login ,
37
- Browse ,
38
- }
39
-
40
- /// Handle user authentication
41
- #[ derive( PartialEq , Eq ) ]
42
- pub enum AuthenticateState {
43
- NotAuthenticated ,
44
- DeviceFlow ( DeviceAuthorizationResponse ) ,
45
- Authenticated ,
46
- }
47
-
48
- pub struct LoginState {
49
- pub login_methods : Login ,
50
- pub auth_state : AuthenticateState ,
51
- }
52
-
53
- pub struct State {
54
- pub screen : Screen ,
55
- pub login : LoginState ,
56
- pub components : Components ,
57
- }
58
-
59
28
pub struct Application {
60
29
terminal : Terminal ,
61
30
client : Client ,
62
31
jobs : Jobs ,
63
- state : State ,
32
+ components : Components ,
64
33
theme : Theme ,
65
34
idle_timer : Pin < Box < Sleep > > ,
66
35
@@ -75,36 +44,21 @@ pub enum EventLoopControlFlow {
75
44
76
45
impl Application {
77
46
pub fn new ( terminal : Terminal , client : Client ) -> Self {
78
- let state = State {
79
- screen : Screen :: Login ,
80
- login : LoginState {
81
- login_methods : Login :: new ( ) ,
82
- auth_state : AuthenticateState :: NotAuthenticated ,
83
- } ,
84
- components : Components {
85
- tabs : Tabs :: new ( ) ,
86
- prompt : Prompt :: new ( ) ,
87
- subscription : Subscription :: new ( ) ,
88
- entries : Entries :: new ( ) ,
89
- } ,
90
- } ;
91
-
92
47
Self {
93
48
terminal,
94
49
client,
50
+ components : Components :: new ( ) ,
95
51
jobs : Jobs :: new ( ) ,
96
- state,
97
52
theme : Theme :: new ( ) ,
98
53
idle_timer : Box :: pin ( tokio:: time:: sleep ( Duration :: from_millis ( 250 ) ) ) ,
99
54
should_quit : false ,
100
55
should_render : false ,
101
56
}
102
57
}
103
58
104
- pub fn set_auth ( & mut self , auth : Authentication ) {
105
- self . client . set_credential ( auth) ;
106
- self . state . login . auth_state = AuthenticateState :: Authenticated ;
107
- self . state . screen = Screen :: Browse ;
59
+ pub fn set_credential ( & mut self , cred : Credential ) {
60
+ self . client . set_credential ( cred) ;
61
+ self . components . auth . authenticated ( ) ;
108
62
self . initial_fetch ( ) ;
109
63
self . should_render = true ;
110
64
}
@@ -172,7 +126,7 @@ impl Application {
172
126
if self . should_render {
173
127
self . render ( ) ;
174
128
self . should_render = false ;
175
- self . state . components . prompt . clear_error_message ( ) ;
129
+ self . components . prompt . clear_error_message ( ) ;
176
130
}
177
131
178
132
if self . should_quit {
@@ -206,10 +160,8 @@ impl Application {
206
160
self . complete_device_authroize_flow ( device_access_token)
207
161
}
208
162
Command :: MoveTabSelection ( direction) => {
209
- match self . state . components . tabs . move_selection ( direction) {
210
- Tab :: Subscription
211
- if !self . state . components . subscription . has_subscription ( ) =>
212
- {
163
+ match self . components . tabs . move_selection ( direction) {
164
+ Tab :: Subscription if !self . components . subscription . has_subscription ( ) => {
213
165
next = Some ( Command :: FetchSubscription {
214
166
after : None ,
215
167
first : 50 ,
@@ -220,7 +172,7 @@ impl Application {
220
172
self . should_render = true ;
221
173
}
222
174
Command :: MoveSubscribedFeed ( direction) => {
223
- self . state . components . subscription . move_selection ( direction) ;
175
+ self . components . subscription . move_selection ( direction) ;
224
176
self . should_render = true ;
225
177
}
226
178
Command :: PromptFeedSubscription => {
@@ -243,18 +195,15 @@ impl Application {
243
195
self . fetch_subscription ( after, first)
244
196
}
245
197
Command :: UpdateSubscription ( sub) => {
246
- self . state . components . subscription . update_subscription ( sub) ;
198
+ self . components . subscription . update_subscription ( sub) ;
247
199
self . should_render = true ;
248
200
}
249
201
Command :: CompleteSubscribeFeed { feed } => {
250
- self . state . components . subscription . add_subscribed_feed ( feed) ;
202
+ self . components . subscription . add_subscribed_feed ( feed) ;
251
203
self . should_render = true ;
252
204
}
253
205
Command :: CompleteUnsubscribeFeed { url } => {
254
- self . state
255
- . components
256
- . subscription
257
- . remove_unsubscribed_feed ( url) ;
206
+ self . components . subscription . remove_unsubscribed_feed ( url) ;
258
207
self . should_render = true ;
259
208
}
260
209
Command :: OpenFeed => {
@@ -264,31 +213,30 @@ impl Application {
264
213
self . fetch_entries ( after, first) ;
265
214
}
266
215
Command :: UpdateEntries ( payload) => {
267
- self . state . components . entries . update_entries ( payload) ;
216
+ self . components . entries . update_entries ( payload) ;
268
217
self . should_render = true ;
269
218
}
270
219
Command :: MoveEntry ( direction) => {
271
- self . state . components . entries . move_selection ( direction) ;
220
+ self . components . entries . move_selection ( direction) ;
272
221
self . should_render = true ;
273
222
}
274
223
Command :: OpenEntry => {
275
224
self . open_entry ( ) ;
276
225
}
277
226
Command :: HandleError { message } => {
278
- self . state . components . prompt . set_error_message ( message) ;
227
+ self . components . prompt . set_error_message ( message) ;
279
228
self . should_render = true ;
280
229
}
281
230
}
282
231
}
283
232
}
284
233
285
234
fn render ( & mut self ) {
286
- let cx = ui:: Context {
287
- state : & mut self . state ,
288
- theme : & self . theme ,
289
- } ;
235
+ let cx = ui:: Context { theme : & self . theme } ;
236
+ let root = Root :: new ( & self . components , cx) ;
290
237
291
- self . terminal . render ( |frame| ui:: render ( frame, cx) ) . unwrap ( ) ;
238
+ self . terminal
239
+ . render ( |frame| Widget :: render ( root, frame. size ( ) , frame. buffer_mut ( ) ) ) ;
292
240
}
293
241
294
242
#[ allow( clippy:: single_match) ]
@@ -458,11 +406,6 @@ impl Application {
458
406
}
459
407
}
460
408
461
- #[ derive( Debug ) ]
462
- pub enum AuthenticateMethod {
463
- Github ,
464
- }
465
-
466
409
impl Application {
467
410
fn authenticate ( & mut self , method : AuthenticateMethod ) {
468
411
match method {
@@ -512,9 +455,9 @@ impl Application {
512
455
} ;
513
456
514
457
// TODO: handle error
515
- auth:: persist_authentication ( auth. clone ( ) ) . ok ( ) ;
458
+ auth:: persist_credential ( auth. clone ( ) ) . ok ( ) ;
516
459
517
- self . set_auth ( auth) ;
460
+ self . set_credential ( auth) ;
518
461
}
519
462
}
520
463
0 commit comments