Skip to content

Commit f8a3551

Browse files
committed
wip: refactor...
1 parent fe09806 commit f8a3551

File tree

11 files changed

+255
-201
lines changed

11 files changed

+255
-201
lines changed

syndapi/src/persistence/memory.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct MemoryDatastore {
1313

1414
const TEST_DATA: &[&str] = &[
1515
"https://seanmonstar.com/rss",
16-
"https://thesquareplanet.com/blog/feed.xml",
16+
"https://thesquareplanet.com/feed.xml",
1717
"https://thiscute.world/en/index.xml",
1818
"https://blog.m-ou.se/index.xml",
1919
"https://keens.github.io/index.xml",

syndterm/src/application/mod.rs

+24-81
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,34 @@ use std::{pin::Pin, time::Duration};
22

33
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyEventKind};
44
use futures_util::{FutureExt, Stream, StreamExt};
5+
use ratatui::widgets::Widget;
56
use tokio::time::{Instant, Sleep};
67

78
use crate::{
89
auth::{
910
self,
1011
device_flow::{DeviceAccessTokenResponse, DeviceAuthorizationResponse},
11-
Authentication,
12+
Credential,
1213
},
1314
client::Client,
1415
command::Command,
1516
job::Jobs,
1617
terminal::Terminal,
1718
ui::{
1819
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},
2721
theme::Theme,
2822
},
2923
};
3024

3125
mod direction;
3226
pub use direction::{Direction, IndexOutOfRange};
3327

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-
5928
pub struct Application {
6029
terminal: Terminal,
6130
client: Client,
6231
jobs: Jobs,
63-
state: State,
32+
components: Components,
6433
theme: Theme,
6534
idle_timer: Pin<Box<Sleep>>,
6635

@@ -75,36 +44,21 @@ pub enum EventLoopControlFlow {
7544

7645
impl Application {
7746
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-
9247
Self {
9348
terminal,
9449
client,
50+
components: Components::new(),
9551
jobs: Jobs::new(),
96-
state,
9752
theme: Theme::new(),
9853
idle_timer: Box::pin(tokio::time::sleep(Duration::from_millis(250))),
9954
should_quit: false,
10055
should_render: false,
10156
}
10257
}
10358

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();
10862
self.initial_fetch();
10963
self.should_render = true;
11064
}
@@ -172,7 +126,7 @@ impl Application {
172126
if self.should_render {
173127
self.render();
174128
self.should_render = false;
175-
self.state.components.prompt.clear_error_message();
129+
self.components.prompt.clear_error_message();
176130
}
177131

178132
if self.should_quit {
@@ -206,10 +160,8 @@ impl Application {
206160
self.complete_device_authroize_flow(device_access_token)
207161
}
208162
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() => {
213165
next = Some(Command::FetchSubscription {
214166
after: None,
215167
first: 50,
@@ -220,7 +172,7 @@ impl Application {
220172
self.should_render = true;
221173
}
222174
Command::MoveSubscribedFeed(direction) => {
223-
self.state.components.subscription.move_selection(direction);
175+
self.components.subscription.move_selection(direction);
224176
self.should_render = true;
225177
}
226178
Command::PromptFeedSubscription => {
@@ -243,18 +195,15 @@ impl Application {
243195
self.fetch_subscription(after, first)
244196
}
245197
Command::UpdateSubscription(sub) => {
246-
self.state.components.subscription.update_subscription(sub);
198+
self.components.subscription.update_subscription(sub);
247199
self.should_render = true;
248200
}
249201
Command::CompleteSubscribeFeed { feed } => {
250-
self.state.components.subscription.add_subscribed_feed(feed);
202+
self.components.subscription.add_subscribed_feed(feed);
251203
self.should_render = true;
252204
}
253205
Command::CompleteUnsubscribeFeed { url } => {
254-
self.state
255-
.components
256-
.subscription
257-
.remove_unsubscribed_feed(url);
206+
self.components.subscription.remove_unsubscribed_feed(url);
258207
self.should_render = true;
259208
}
260209
Command::OpenFeed => {
@@ -264,31 +213,30 @@ impl Application {
264213
self.fetch_entries(after, first);
265214
}
266215
Command::UpdateEntries(payload) => {
267-
self.state.components.entries.update_entries(payload);
216+
self.components.entries.update_entries(payload);
268217
self.should_render = true;
269218
}
270219
Command::MoveEntry(direction) => {
271-
self.state.components.entries.move_selection(direction);
220+
self.components.entries.move_selection(direction);
272221
self.should_render = true;
273222
}
274223
Command::OpenEntry => {
275224
self.open_entry();
276225
}
277226
Command::HandleError { message } => {
278-
self.state.components.prompt.set_error_message(message);
227+
self.components.prompt.set_error_message(message);
279228
self.should_render = true;
280229
}
281230
}
282231
}
283232
}
284233

285234
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);
290237

291-
self.terminal.render(|frame| ui::render(frame, cx)).unwrap();
238+
self.terminal
239+
.render(|frame| Widget::render(root, frame.size(), frame.buffer_mut()));
292240
}
293241

294242
#[allow(clippy::single_match)]
@@ -458,11 +406,6 @@ impl Application {
458406
}
459407
}
460408

461-
#[derive(Debug)]
462-
pub enum AuthenticateMethod {
463-
Github,
464-
}
465-
466409
impl Application {
467410
fn authenticate(&mut self, method: AuthenticateMethod) {
468411
match method {
@@ -512,9 +455,9 @@ impl Application {
512455
};
513456

514457
// TODO: handle error
515-
auth::persist_authentication(auth.clone()).ok();
458+
auth::persist_credential(auth.clone()).ok();
516459

517-
self.set_auth(auth);
460+
self.set_credential(auth);
518461
}
519462
}
520463

syndterm/src/auth/mod.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,36 @@ use crate::config;
88
pub mod device_flow;
99
pub mod github;
1010

11+
#[derive(Debug, Clone, Copy)]
12+
pub enum AuthenticationProvider {
13+
Github,
14+
}
15+
1116
#[derive(Serialize, Deserialize, Clone)]
12-
pub enum Authentication {
17+
pub enum Credential {
1318
Github { access_token: String },
1419
}
1520

16-
pub fn persist_authentication(auth: Authentication) -> anyhow::Result<()> {
17-
let auth_path = auth_file();
18-
if let Some(parent) = auth_path.parent() {
21+
pub fn persist_credential(cred: Credential) -> anyhow::Result<()> {
22+
let cred_path = cred_file();
23+
if let Some(parent) = cred_path.parent() {
1924
std::fs::create_dir_all(parent)?;
2025
}
21-
let mut auth_file = std::fs::File::create(&auth_path)?;
26+
let mut cred_file = std::fs::File::create(&cred_path)?;
2227

23-
debug!(path = ?auth_path.display(), "Create auth cache file");
28+
debug!(path = ?cred_path.display(), "Create credential cache file");
2429

25-
serde_json::to_writer(&mut auth_file, &auth)?;
30+
serde_json::to_writer(&mut cred_file, &cred)?;
2631

2732
Ok(())
2833
}
2934

30-
fn auth_file() -> PathBuf {
31-
config::cache_dir().join("auth.json")
35+
fn cred_file() -> PathBuf {
36+
config::cache_dir().join("credential.json")
3237
}
3338

34-
pub fn authenticate_from_cache() -> Option<Authentication> {
35-
std::fs::File::open(auth_file())
39+
pub fn credential_from_cache() -> Option<Credential> {
40+
std::fs::File::open(cred_file())
3641
.ok()
3742
.and_then(|f| serde_json::from_reader(f).ok())
3843
}

syndterm/src/client/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::{de::DeserializeOwned, Serialize};
77
use tracing::error;
88
use url::Url;
99

10-
use crate::{auth::Authentication, config, types};
10+
use crate::{auth::Credential, config, types};
1111

1212
use self::query::subscription::SubscriptionOutput;
1313

@@ -39,9 +39,9 @@ impl Client {
3939
})
4040
}
4141

42-
pub fn set_credential(&mut self, auth: Authentication) {
42+
pub fn set_credential(&mut self, auth: Credential) {
4343
let mut token = HeaderValue::try_from(match auth {
44-
Authentication::Github { access_token } => format!("github {access_token}"),
44+
Credential::Github { access_token } => format!("github {access_token}"),
4545
})
4646
.unwrap();
4747
token.set_sensitive(true);

syndterm/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ async fn main() {
6969
Application::new(terminal, client)
7070
};
7171

72-
if let Some(auth) = auth::authenticate_from_cache() {
72+
if let Some(auth) = auth::credential_from_cache() {
7373
info!("Use authentication cache");
74-
app.set_auth(auth);
74+
app.set_credential(auth);
7575
}
7676

7777
info!("Running...");

0 commit comments

Comments
 (0)