Refactored things a bit and added help text support

This commit is contained in:
2023-08-08 10:50:04 -06:00
parent ff6e392af1
commit 3f378fb25a
11 changed files with 307 additions and 257 deletions
+3 -14
View File
@@ -7,26 +7,13 @@ use serde::{Deserialize, Serialize};
use tokio::sync::mpsc::Sender;
use tokio::time::Instant;
use crate::app::models::{HorizontallyScrollableText, TabRoute, TabState};
use crate::app::radarr::{ActiveRadarrBlock, RadarrData};
use crate::models::{HorizontallyScrollableText, Route, TabRoute, TabState};
use crate::network::NetworkEvent;
pub(crate) mod key_binding;
pub mod models;
pub mod radarr;
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Route {
Radarr(ActiveRadarrBlock),
Sonarr,
}
impl From<ActiveRadarrBlock> for Route {
fn from(active_radarr_block: ActiveRadarrBlock) -> Route {
Route::Radarr(active_radarr_block)
}
}
const DEFAULT_ROUTE: Route = Route::Radarr(ActiveRadarrBlock::Movies);
pub struct App {
@@ -130,10 +117,12 @@ impl Default for App {
TabRoute {
title: "Radarr".to_owned(),
route: ActiveRadarrBlock::Movies.into(),
help: "<tab> change servarr | <?> help | <q> quit ".to_owned(),
},
TabRoute {
title: "Sonarr".to_owned(),
route: Route::Sonarr,
help: "<tab> change servarr | <?> help | <q> quit ".to_owned(),
},
]),
client: Client::new(),
-196
View File
@@ -1,196 +0,0 @@
use std::cell::RefCell;
use std::fmt::{Display, Formatter};
use serde::Deserialize;
use tui::widgets::TableState;
use crate::app::Route;
pub trait Scrollable {
fn scroll_down(&mut self);
fn scroll_up(&mut self);
}
pub struct StatefulTable<T> {
pub state: TableState,
pub items: Vec<T>,
}
impl<T> Default for StatefulTable<T> {
fn default() -> StatefulTable<T> {
StatefulTable {
state: TableState::default(),
items: Vec::new(),
}
}
}
impl<T: Clone> StatefulTable<T> {
pub fn set_items(&mut self, items: Vec<T>) {
let items_len = items.len();
self.items = items;
if !self.items.is_empty() {
let selected_row = self.state.selected().map_or(0, |i| {
if i > 0 && i < items_len {
i
} else if i >= items_len {
items_len - 1
} else {
0
}
});
self.state.select(Some(selected_row));
}
}
pub fn current_selection(&self) -> &T {
&self.items[self.state.selected().unwrap_or(0)]
}
pub fn current_selection_clone(&self) -> T {
self.items[self.state.selected().unwrap_or(0)].clone()
}
}
impl<T> Scrollable for StatefulTable<T> {
fn scroll_down(&mut self) {
let selected_row = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(selected_row));
}
fn scroll_up(&mut self) {
let selected_row = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(selected_row));
}
}
#[derive(Default)]
pub struct ScrollableText {
pub items: Vec<String>,
pub offset: u16,
}
impl ScrollableText {
pub fn with_string(item: String) -> ScrollableText {
let items: Vec<&str> = item.split('\n').collect();
let items: Vec<String> = items.iter().map(|it| it.to_string()).collect();
ScrollableText { items, offset: 0 }
}
pub fn get_text(&self) -> String {
self.items.join("\n")
}
}
impl Scrollable for ScrollableText {
fn scroll_down(&mut self) {
if self.offset < self.items.len() as u16 {
self.offset += 1;
}
}
fn scroll_up(&mut self) {
if self.offset > 0 {
self.offset -= 1;
}
}
}
#[derive(Default, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(from = "String")]
pub struct HorizontallyScrollableText {
pub text: String,
pub offset: RefCell<usize>,
}
impl From<String> for HorizontallyScrollableText {
fn from(input: String) -> HorizontallyScrollableText {
HorizontallyScrollableText::new(input)
}
}
impl Display for HorizontallyScrollableText {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if *self.offset.borrow() == 0 {
write!(f, "{}", self.text)
} else {
write!(f, "{}", &self.text[*self.offset.borrow()..])
}
}
}
impl HorizontallyScrollableText {
pub fn new(input: String) -> HorizontallyScrollableText {
HorizontallyScrollableText {
text: format!("{} ", input),
offset: RefCell::new(0),
}
}
pub fn scroll_text(&self) {
let new_offset = *self.offset.borrow() + 1;
*self.offset.borrow_mut() = new_offset % self.text.len();
}
pub fn reset_offset(&self) {
*self.offset.borrow_mut() = 0;
}
}
#[derive(Clone)]
pub struct TabRoute {
pub title: String,
pub route: Route,
}
pub struct TabState {
pub tabs: Vec<TabRoute>,
pub index: usize,
}
impl TabState {
pub fn new(tabs: Vec<TabRoute>) -> TabState {
TabState { tabs, index: 0 }
}
pub fn set_index(&mut self, index: usize) -> &TabRoute {
self.index = index;
&self.tabs[self.index]
}
pub fn get_active_route(&self) -> &Route {
&self.tabs[self.index].route
}
pub fn next(&mut self) {
self.index = (self.index + 1) % self.tabs.len();
}
pub fn previous(&mut self) {
if self.index > 0 {
self.index -= 1;
} else {
self.index = self.tabs.len() - 1;
}
}
}
+18 -4
View File
@@ -4,12 +4,12 @@ use std::time::Duration;
use chrono::{DateTime, Utc};
use strum::EnumIter;
use crate::app::models::{ScrollableText, StatefulTable, TabRoute, TabState};
use crate::app::App;
use crate::network::radarr_network::{
use crate::app::{App, Route};
use crate::models::radarr_models::{
Collection, CollectionMovie, Credit, DiskSpace, DownloadRecord, Movie, MovieHistoryItem,
RadarrEvent,
};
use crate::models::{ScrollableText, StatefulTable, TabRoute, TabState};
use crate::network::radarr_network::RadarrEvent;
pub struct RadarrData {
pub disk_space_vec: Vec<DiskSpace>,
@@ -74,36 +74,44 @@ impl Default for RadarrData {
TabRoute {
title: "Library".to_owned(),
route: ActiveRadarrBlock::Movies.into(),
help: "<↑↓> scroll table | <enter> movie details | ←→ change tab ".to_owned(),
},
TabRoute {
title: "Downloads".to_owned(),
route: ActiveRadarrBlock::Downloads.into(),
help: "<↑↓> scroll table | ←→ change tab ".to_owned(),
},
TabRoute {
title: "Collections".to_owned(),
route: ActiveRadarrBlock::Collections.into(),
help: "<↑↓> scroll table | <enter> collection details | ←→ change tab ".to_owned(),
},
]),
movie_info_tabs: TabState::new(vec![
TabRoute {
title: "Details".to_owned(),
route: ActiveRadarrBlock::MovieDetails.into(),
help: "←→ change tab | <esc> close ".to_owned(),
},
TabRoute {
title: "History".to_owned(),
route: ActiveRadarrBlock::MovieHistory.into(),
help: "<↑↓> scroll table | ←→ change tab | <esc> close ".to_owned(),
},
TabRoute {
title: "File".to_owned(),
route: ActiveRadarrBlock::FileInfo.into(),
help: "←→ change tab | <esc> close ".to_owned(),
},
TabRoute {
title: "Cast".to_owned(),
route: ActiveRadarrBlock::Cast.into(),
help: "<↑↓> scroll table | ←→ change tab | <esc> close ".to_owned(),
},
TabRoute {
title: "Crew".to_owned(),
route: ActiveRadarrBlock::Crew.into(),
help: "<↑↓> scroll table | ←→ change tab | <esc> close ".to_owned(),
},
]),
}
@@ -131,6 +139,12 @@ pub enum ActiveRadarrBlock {
ViewMovieOverview,
}
impl From<ActiveRadarrBlock> for Route {
fn from(active_radarr_block: ActiveRadarrBlock) -> Route {
Route::Radarr(active_radarr_block)
}
}
impl App {
pub(super) async fn dispatch_by_radarr_block(&mut self, active_radarr_block: &ActiveRadarrBlock) {
match active_radarr_block {