Skip to content

Commit 6b88f86

Browse files
committed
Feat: refactor-ished
1 parent 934c627 commit 6b88f86

File tree

7 files changed

+338
-323
lines changed

7 files changed

+338
-323
lines changed

src/cmd/submit.rs

Lines changed: 50 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -9,124 +9,16 @@ use ratatui::prelude::*;
99
use ratatui::widgets::ListState;
1010
use tokio::task::JoinHandle;
1111

12-
use crate::models::{AppState, GpuItem, LeaderboardItem, SubmissionModeItem};
13-
use crate::views::selection::SelectionItem;
12+
use crate::models::{
13+
AppState, GpuItem, GpuSelectionView, LeaderboardItem, LeaderboardSelectionView,
14+
SelectionAction, SelectionItem, SelectionView, SubmissionModeItem, SubmissionModeSelectionView,
15+
};
1416
use crate::service;
1517
use crate::utils;
18+
use crate::views::file_selection_page::{FileSelectionAction, FileSelectionView};
1619
use crate::views::loading_page::{LoadingPage, LoadingPageState};
17-
use crate::views::result_page::{ResultPageState, ResultView, ResultAction};
18-
use crate::views::welcome_page::{WelcomeView, WelcomeAction};
19-
use crate::views::file_selection_page::{FileSelectionView, FileSelectionAction};
20-
use crate::views::selection::{SelectionView, SelectionAction};
21-
22-
// Selection view implementations for different types
23-
pub struct LeaderboardSelectionView {
24-
leaderboards: Vec<LeaderboardItem>,
25-
leaderboards_state: ListState,
26-
}
27-
28-
impl LeaderboardSelectionView {
29-
pub fn new(leaderboards: Vec<LeaderboardItem>) -> Self {
30-
let mut state = ListState::default();
31-
state.select(Some(0));
32-
Self {
33-
leaderboards,
34-
leaderboards_state: state,
35-
}
36-
}
37-
}
38-
39-
impl SelectionView<LeaderboardItem> for LeaderboardSelectionView {
40-
fn title(&self) -> String {
41-
"Select Leaderboard".to_string()
42-
}
43-
44-
fn items(&self) -> &[LeaderboardItem] {
45-
&self.leaderboards
46-
}
47-
48-
fn state(&self) -> &ListState {
49-
&self.leaderboards_state
50-
}
51-
52-
fn state_mut(&mut self) -> &mut ListState {
53-
&mut self.leaderboards_state
54-
}
55-
}
56-
57-
pub struct GpuSelectionView {
58-
gpus: Vec<GpuItem>,
59-
gpus_state: ListState,
60-
leaderboard_name: String,
61-
}
62-
63-
impl GpuSelectionView {
64-
pub fn new(gpus: Vec<GpuItem>, leaderboard_name: String) -> Self {
65-
let mut state = ListState::default();
66-
state.select(Some(0));
67-
Self {
68-
gpus,
69-
gpus_state: state,
70-
leaderboard_name,
71-
}
72-
}
73-
}
74-
75-
impl SelectionView<GpuItem> for GpuSelectionView {
76-
fn title(&self) -> String {
77-
format!("Select GPU for '{}'", self.leaderboard_name)
78-
}
79-
80-
fn items(&self) -> &[GpuItem] {
81-
&self.gpus
82-
}
83-
84-
fn state(&self) -> &ListState {
85-
&self.gpus_state
86-
}
87-
88-
fn state_mut(&mut self) -> &mut ListState {
89-
&mut self.gpus_state
90-
}
91-
}
92-
93-
pub struct SubmissionModeSelectionView {
94-
submission_modes: Vec<SubmissionModeItem>,
95-
submission_modes_state: ListState,
96-
leaderboard_name: String,
97-
gpu_name: String,
98-
}
99-
100-
impl SubmissionModeSelectionView {
101-
pub fn new(submission_modes: Vec<SubmissionModeItem>, leaderboard_name: String, gpu_name: String) -> Self {
102-
let mut state = ListState::default();
103-
state.select(Some(0));
104-
Self {
105-
submission_modes,
106-
submission_modes_state: state,
107-
leaderboard_name,
108-
gpu_name,
109-
}
110-
}
111-
}
112-
113-
impl SelectionView<SubmissionModeItem> for SubmissionModeSelectionView {
114-
fn title(&self) -> String {
115-
format!("Select Submission Mode for '{}' on '{}'", self.leaderboard_name, self.gpu_name)
116-
}
117-
118-
fn items(&self) -> &[SubmissionModeItem] {
119-
&self.submission_modes
120-
}
121-
122-
fn state(&self) -> &ListState {
123-
&self.submission_modes_state
124-
}
125-
126-
fn state_mut(&mut self) -> &mut ListState {
127-
&mut self.submission_modes_state
128-
}
129-
}
20+
use crate::views::result_page::{ResultAction, ResultPageState, ResultView};
21+
use crate::views::welcome_page::{WelcomeAction, WelcomeView};
13022

13123
#[derive(Default)]
13224
pub struct App {
@@ -293,7 +185,9 @@ impl App {
293185
return Ok(true);
294186
}
295187
WelcomeAction::ViewHistory => {
296-
self.show_error("View History feature is not yet implemented".to_string());
188+
self.show_error(
189+
"View History feature is not yet implemented".to_string(),
190+
);
297191
return Ok(true);
298192
}
299193
WelcomeAction::Handled => return Ok(true),
@@ -306,28 +200,35 @@ impl App {
306200
match view.handle_key_event(key)? {
307201
FileSelectionAction::FileSelected(filepath) => {
308202
self.filepath = filepath.clone();
309-
203+
310204
// Parse directives from the selected file
311205
match utils::get_popcorn_directives(&filepath) {
312206
Ok((directives, has_multiple_gpus)) => {
313207
if has_multiple_gpus {
314208
self.show_error("Multiple GPUs are not supported yet. Please specify only one GPU.".to_string());
315209
return Ok(true);
316210
}
317-
211+
318212
// Apply directives to determine next state
319213
self.initialize_with_directives(directives);
320-
214+
321215
// Spawn appropriate task based on the new state
216+
// TODO: make spawn_x tasks also show error if they fail, a lot of duplicate code
322217
match self.app_state {
323218
AppState::LeaderboardSelection => {
324219
if let Err(e) = self.spawn_load_leaderboards() {
325-
self.show_error(format!("Error starting leaderboard fetch: {}", e));
220+
self.show_error(format!(
221+
"Error starting leaderboard fetch: {}",
222+
e
223+
));
326224
}
327225
}
328226
AppState::GpuSelection => {
329227
if let Err(e) = self.spawn_load_gpus() {
330-
self.show_error(format!("Error starting GPU fetch: {}", e));
228+
self.show_error(format!(
229+
"Error starting GPU fetch: {}",
230+
e
231+
));
331232
}
332233
}
333234
AppState::SubmissionModeSelection => {
@@ -337,15 +238,17 @@ impl App {
337238
}
338239
}
339240
Err(e) => {
340-
self.show_error(format!("Error parsing file directives: {}", e));
241+
self.show_error(format!(
242+
"Error parsing file directives: {}",
243+
e
244+
));
341245
return Ok(true);
342246
}
343247
}
344248
return Ok(true);
345249
}
346250
FileSelectionAction::Handled => return Ok(true),
347251
FileSelectionAction::NotHandled => return Ok(false),
348-
_ => return Ok(true),
349252
}
350253
}
351254
}
@@ -354,7 +257,7 @@ impl App {
354257
match view.handle_key_event(key) {
355258
SelectionAction::Selected(idx) => {
356259
self.selected_leaderboard = Some(view.items()[idx].title().to_string());
357-
260+
358261
if self.selected_gpu.is_none() {
359262
self.app_state = AppState::GpuSelection;
360263
if let Err(e) = self.spawn_load_gpus() {
@@ -492,7 +395,7 @@ impl App {
492395
Ok(Ok(leaderboards)) => {
493396
self.leaderboards = leaderboards.clone();
494397
self.leaderboard_view = Some(LeaderboardSelectionView::new(leaderboards));
495-
398+
496399
if let Some(selected_name) = &self.selected_leaderboard {
497400
if let Some(index) = self
498401
.leaderboards
@@ -504,11 +407,12 @@ impl App {
504407
}
505408
if self.selected_gpu.is_some() {
506409
self.app_state = AppState::SubmissionModeSelection;
507-
self.submission_mode_view = Some(SubmissionModeSelectionView::new(
508-
self.submission_modes.clone(),
509-
self.selected_leaderboard.as_ref().unwrap().clone(),
510-
self.selected_gpu.as_ref().unwrap().clone(),
511-
));
410+
self.submission_mode_view =
411+
Some(SubmissionModeSelectionView::new(
412+
self.submission_modes.clone(),
413+
self.selected_leaderboard.as_ref().unwrap().clone(),
414+
self.selected_gpu.as_ref().unwrap().clone(),
415+
));
512416
} else {
513417
self.app_state = AppState::GpuSelection;
514418
if let Err(e) = self.spawn_load_gpus() {
@@ -527,9 +431,7 @@ impl App {
527431
view.state_mut().select(Some(0));
528432
}
529433
}
530-
Ok(Err(e)) => {
531-
self.show_error(format!("Error fetching leaderboards: {}", e))
532-
}
434+
Ok(Err(e)) => self.show_error(format!("Error fetching leaderboards: {}", e)),
533435
Err(e) => self.show_error(format!("Task join error: {}", e)),
534436
}
535437
}
@@ -545,9 +447,12 @@ impl App {
545447
self.gpus = gpus.clone();
546448
self.gpu_view = Some(GpuSelectionView::new(
547449
gpus,
548-
self.selected_leaderboard.as_ref().unwrap_or(&"N/A".to_string()).clone(),
450+
self.selected_leaderboard
451+
.as_ref()
452+
.unwrap_or(&"N/A".to_string())
453+
.clone(),
549454
));
550-
455+
551456
if let Some(selected_name) = &self.selected_gpu {
552457
if let Some(index) = self
553458
.gpus
@@ -589,24 +494,28 @@ impl App {
589494
Ok(Ok(status)) => {
590495
// Process the status text
591496
let trimmed = status.trim();
592-
let content = if trimmed.starts_with('[') && trimmed.ends_with(']') && trimmed.len() >= 2 {
497+
let content = if trimmed.starts_with('[')
498+
&& trimmed.ends_with(']')
499+
&& trimmed.len() >= 2
500+
{
593501
&trimmed[1..trimmed.len() - 1]
594502
} else {
595503
trimmed
596504
};
597505
let content = content.replace("\\n", "\n");
598-
506+
599507
// Create result view and transition to showing result
600508
self.result_view = Some(ResultView::new(content));
601509
self.app_state = AppState::ShowingResult;
602510
}
603511
Ok(Err(e)) => {
604512
// Show error in result view
605-
self.result_view = Some(ResultView::new(format!("Submission error: {}", e)));
513+
self.result_view =
514+
Some(ResultView::new(format!("Submission error: {}", e)));
606515
self.app_state = AppState::ShowingResult;
607516
}
608517
Err(e) => {
609-
// Show task join error in result view
518+
// Show task join error in result view
610519
self.result_view = Some(ResultView::new(format!("Task join error: {}", e)));
611520
self.app_state = AppState::ShowingResult;
612521
}
@@ -690,7 +599,7 @@ pub async fn run_submit_tui(
690599

691600
// First apply directives as defaults
692601
app.initialize_with_directives(directives);
693-
602+
694603
// Then override with CLI flags if provided
695604
if let Some(gpu_flag) = gpu {
696605
app.selected_gpu = Some(gpu_flag);
@@ -761,4 +670,4 @@ pub async fn run_submit_tui(
761670
terminal.show_cursor()?;
762671

763672
Ok(())
764-
}
673+
}

0 commit comments

Comments
 (0)