From 9927251c961fa05108b1f842af482169e692a123 Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 15:53:52 +0200 Subject: [PATCH 1/6] refactor: split cli and tui --- rm-main/src/{cli.rs => cli/mod.rs} | 0 rm-main/src/main.rs | 7 ++----- rm-main/src/transmission/fetchers.rs | 3 ++- rm-main/src/{ => tui}/app.rs | 16 ++++++++-------- rm-main/src/{tui.rs => tui/mod.rs} | 3 +++ rm-main/src/{ => tui}/ui/components/mod.rs | 0 rm-main/src/{ => tui}/ui/components/table.rs | 0 rm-main/src/{ => tui}/ui/components/tabs.rs | 3 ++- rm-main/src/{ => tui}/ui/global_popups/error.rs | 5 +++-- rm-main/src/{ => tui}/ui/global_popups/help.rs | 13 +++++++------ rm-main/src/{ => tui}/ui/global_popups/mod.rs | 3 ++- rm-main/src/{ => tui}/ui/mod.rs | 8 ++++---- rm-main/src/{ => tui}/ui/tabs/mod.rs | 0 .../src/{ => tui}/ui/tabs/search/bottom_bar.rs | 2 +- rm-main/src/{ => tui}/ui/tabs/search/mod.rs | 10 ++++++---- .../src/{ => tui}/ui/tabs/search/popups/mod.rs | 7 +++---- .../{ => tui}/ui/tabs/search/popups/providers.rs | 2 +- .../{ => tui}/ui/tabs/torrents/bottom_stats.rs | 2 +- .../{ => tui}/ui/tabs/torrents/input_manager.rs | 2 +- rm-main/src/{ => tui}/ui/tabs/torrents/mod.rs | 7 ++++--- .../{ => tui}/ui/tabs/torrents/popups/files.rs | 10 ++++++---- .../src/{ => tui}/ui/tabs/torrents/popups/mod.rs | 5 +++-- .../{ => tui}/ui/tabs/torrents/popups/stats.rs | 5 +++-- .../ui/tabs/torrents/rustmission_torrent.rs | 0 .../{ => tui}/ui/tabs/torrents/table_manager.rs | 2 +- .../{ => tui}/ui/tabs/torrents/task_manager.rs | 9 +++++---- .../ui/tabs/torrents/tasks/add_magnet.rs | 12 +++++++----- .../{ => tui}/ui/tabs/torrents/tasks/default.rs | 4 ++-- .../ui/tabs/torrents/tasks/delete_torrent.rs | 14 +++++--------- .../{ => tui}/ui/tabs/torrents/tasks/filter.rs | 5 +++-- .../src/{ => tui}/ui/tabs/torrents/tasks/mod.rs | 0 .../ui/tabs/torrents/tasks/move_torrent.rs | 12 +++++++----- .../{ => tui}/ui/tabs/torrents/tasks/status.rs | 4 ++-- 33 files changed, 94 insertions(+), 81 deletions(-) rename rm-main/src/{cli.rs => cli/mod.rs} (100%) rename rm-main/src/{ => tui}/app.rs (96%) rename rm-main/src/{tui.rs => tui/mod.rs} (99%) rename rm-main/src/{ => tui}/ui/components/mod.rs (100%) rename rm-main/src/{ => tui}/ui/components/table.rs (100%) rename rm-main/src/{ => tui}/ui/components/tabs.rs (99%) rename rm-main/src/{ => tui}/ui/global_popups/error.rs (98%) rename rm-main/src/{ => tui}/ui/global_popups/help.rs (99%) rename rm-main/src/{ => tui}/ui/global_popups/mod.rs (98%) rename rm-main/src/{ => tui}/ui/mod.rs (97%) rename rm-main/src/{ => tui}/ui/tabs/mod.rs (100%) rename rm-main/src/{ => tui}/ui/tabs/search/bottom_bar.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/search/mod.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/search/popups/mod.rs (93%) rename rm-main/src/{ => tui}/ui/tabs/search/popups/providers.rs (99%) rename rm-main/src/{ => tui}/ui/tabs/torrents/bottom_stats.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/torrents/input_manager.rs (97%) rename rm-main/src/{ => tui}/ui/tabs/torrents/mod.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/torrents/popups/files.rs (99%) rename rm-main/src/{ => tui}/ui/tabs/torrents/popups/mod.rs (99%) rename rm-main/src/{ => tui}/ui/tabs/torrents/popups/stats.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/torrents/rustmission_torrent.rs (100%) rename rm-main/src/{ => tui}/ui/tabs/torrents/table_manager.rs (99%) rename rm-main/src/{ => tui}/ui/tabs/torrents/task_manager.rs (99%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/add_magnet.rs (94%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/default.rs (92%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/delete_torrent.rs (92%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/filter.rs (98%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/mod.rs (100%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/move_torrent.rs (90%) rename rm-main/src/{ => tui}/ui/tabs/torrents/tasks/status.rs (98%) diff --git a/rm-main/src/cli.rs b/rm-main/src/cli/mod.rs similarity index 100% rename from rm-main/src/cli.rs rename to rm-main/src/cli/mod.rs diff --git a/rm-main/src/main.rs b/rm-main/src/main.rs index e4b60a7..843558b 100644 --- a/rm-main/src/main.rs +++ b/rm-main/src/main.rs @@ -1,13 +1,10 @@ -pub mod app; mod cli; pub mod transmission; -pub mod tui; -mod ui; - -use app::App; +mod tui; use anyhow::Result; use clap::Parser; +use tui::app::App; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<()> { diff --git a/rm-main/src/transmission/fetchers.rs b/rm-main/src/transmission/fetchers.rs index 6840123..1d1ef06 100644 --- a/rm-main/src/transmission/fetchers.rs +++ b/rm-main/src/transmission/fetchers.rs @@ -4,9 +4,10 @@ use rm_config::CONFIG; use tokio::sync::oneshot; use transmission_rpc::types::TorrentGetField; -use crate::app; use rm_shared::action::UpdateAction; +use crate::tui::app; + use super::TorrentAction; pub async fn stats(ctx: app::Ctx) { diff --git a/rm-main/src/app.rs b/rm-main/src/tui/app.rs similarity index 96% rename from rm-main/src/app.rs rename to rm-main/src/tui/app.rs index d44d032..c71a41f 100644 --- a/rm-main/src/app.rs +++ b/rm-main/src/tui/app.rs @@ -1,22 +1,22 @@ -use crossterm::event::Event; -use crossterm::event::KeyCode; -use crossterm::event::KeyModifiers; -use rm_config::CONFIG; -use rm_shared::action::Action; -use rm_shared::action::UpdateAction; use std::sync::Arc; -use crate::ui::components::tabs::CurrentTab; +use crate::tui::ui::components::Component; use crate::{ transmission::{self, TorrentAction}, tui::Tui, - ui::{components::Component, MainWindow}, }; +use rm_config::CONFIG; +use rm_shared::action::{Action, UpdateAction}; + use anyhow::{Error, Result}; +use crossterm::event::{Event, KeyCode, KeyModifiers}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use transmission_rpc::{types::SessionGet, TransClient}; +use super::ui::components::tabs::CurrentTab; +use super::ui::MainWindow; + #[derive(Clone)] pub struct Ctx { pub session_info: Arc, diff --git a/rm-main/src/tui.rs b/rm-main/src/tui/mod.rs similarity index 99% rename from rm-main/src/tui.rs rename to rm-main/src/tui/mod.rs index 6cba203..c2eecce 100644 --- a/rm-main/src/tui.rs +++ b/rm-main/src/tui/mod.rs @@ -1,3 +1,6 @@ +pub mod app; +mod ui; + use std::{io, time::Duration}; use anyhow::Result; diff --git a/rm-main/src/ui/components/mod.rs b/rm-main/src/tui/ui/components/mod.rs similarity index 100% rename from rm-main/src/ui/components/mod.rs rename to rm-main/src/tui/ui/components/mod.rs diff --git a/rm-main/src/ui/components/table.rs b/rm-main/src/tui/ui/components/table.rs similarity index 100% rename from rm-main/src/ui/components/table.rs rename to rm-main/src/tui/ui/components/table.rs diff --git a/rm-main/src/ui/components/tabs.rs b/rm-main/src/tui/ui/components/tabs.rs similarity index 99% rename from rm-main/src/ui/components/tabs.rs rename to rm-main/src/tui/ui/components/tabs.rs index c92d8c8..d3986b4 100644 --- a/rm-main/src/ui/components/tabs.rs +++ b/rm-main/src/tui/ui/components/tabs.rs @@ -1,7 +1,8 @@ -use crate::app; use rm_config::CONFIG; use rm_shared::action::Action; +use crate::tui::app; + use super::{Component, ComponentAction}; use ratatui::{layout::Flex, prelude::*, widgets::Tabs}; diff --git a/rm-main/src/ui/global_popups/error.rs b/rm-main/src/tui/ui/global_popups/error.rs similarity index 98% rename from rm-main/src/ui/global_popups/error.rs rename to rm-main/src/tui/ui/global_popups/error.rs index d992e64..ae78082 100644 --- a/rm-main/src/ui/global_popups/error.rs +++ b/rm-main/src/tui/ui/global_popups/error.rs @@ -3,11 +3,12 @@ use ratatui::{ widgets::{Block, Clear, Paragraph, Wrap}, }; -use crate::ui::{ +use rm_shared::action::Action; + +use crate::tui::ui::{ centered_rect, components::{Component, ComponentAction}, }; -use rm_shared::action::Action; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ErrorPopup { diff --git a/rm-main/src/ui/global_popups/help.rs b/rm-main/src/tui/ui/global_popups/help.rs similarity index 99% rename from rm-main/src/ui/global_popups/help.rs rename to rm-main/src/tui/ui/global_popups/help.rs index 32e8ef7..a992b7f 100644 --- a/rm-main/src/ui/global_popups/help.rs +++ b/rm-main/src/tui/ui/global_popups/help.rs @@ -8,18 +8,19 @@ use ratatui::{ }, }; -use crate::{ +use rm_config::{ + keymap::{actions::UserAction, Keybinding}, + CONFIG, +}; +use rm_shared::action::Action; + +use crate::tui::{ app, ui::{ centered_rect, components::{Component, ComponentAction}, }, }; -use rm_config::{ - keymap::{actions::UserAction, Keybinding}, - CONFIG, -}; -use rm_shared::action::Action; macro_rules! add_line { ($lines:expr, $key:expr, $description:expr) => { diff --git a/rm-main/src/ui/global_popups/mod.rs b/rm-main/src/tui/ui/global_popups/mod.rs similarity index 98% rename from rm-main/src/ui/global_popups/mod.rs rename to rm-main/src/tui/ui/global_popups/mod.rs index 1c33b31..c9815ab 100644 --- a/rm-main/src/ui/global_popups/mod.rs +++ b/rm-main/src/tui/ui/global_popups/mod.rs @@ -6,9 +6,10 @@ use ratatui::prelude::*; pub use error::ErrorPopup; pub use help::HelpPopup; -use crate::app; use rm_shared::action::Action; +use crate::tui::app; + use super::components::{Component, ComponentAction}; pub(super) struct GlobalPopupManager { diff --git a/rm-main/src/ui/mod.rs b/rm-main/src/tui/ui/mod.rs similarity index 97% rename from rm-main/src/ui/mod.rs rename to rm-main/src/tui/ui/mod.rs index 0b9451c..56648c7 100644 --- a/rm-main/src/ui/mod.rs +++ b/rm-main/src/tui/ui/mod.rs @@ -2,23 +2,23 @@ pub mod components; pub mod global_popups; pub mod tabs; -use crate::ui::{global_popups::ErrorPopup, tabs::torrents::TorrentsTab}; - use components::ComponentAction; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; +use global_popups::ErrorPopup; use ratatui::prelude::*; +use tabs::torrents::TorrentsTab; use tui_input::InputRequest; use rm_shared::action::{Action, UpdateAction}; -use crate::app::{self}; - use self::{ components::{tabs::CurrentTab, Component, TabComponent}, global_popups::GlobalPopupManager, tabs::search::SearchTab, }; +use super::app; + pub struct MainWindow { pub tabs: TabComponent, torrents_tab: TorrentsTab, diff --git a/rm-main/src/ui/tabs/mod.rs b/rm-main/src/tui/ui/tabs/mod.rs similarity index 100% rename from rm-main/src/ui/tabs/mod.rs rename to rm-main/src/tui/ui/tabs/mod.rs diff --git a/rm-main/src/ui/tabs/search/bottom_bar.rs b/rm-main/src/tui/ui/tabs/search/bottom_bar.rs similarity index 98% rename from rm-main/src/ui/tabs/search/bottom_bar.rs rename to rm-main/src/tui/ui/tabs/search/bottom_bar.rs index 2b74954..3c47b2d 100644 --- a/rm-main/src/ui/tabs/search/bottom_bar.rs +++ b/rm-main/src/tui/ui/tabs/search/bottom_bar.rs @@ -9,7 +9,7 @@ use rm_config::CONFIG; use rm_shared::action::{Action, UpdateAction}; use throbber_widgets_tui::ThrobberState; -use crate::{app, ui::components::Component}; +use crate::tui::{app, ui::components::Component}; use super::{ConfiguredProvider, ProviderState}; diff --git a/rm-main/src/ui/tabs/search/mod.rs b/rm-main/src/tui/ui/tabs/search/mod.rs similarity index 98% rename from rm-main/src/ui/tabs/search/mod.rs rename to rm-main/src/tui/ui/tabs/search/mod.rs index 4f0e43f..921bc09 100644 --- a/rm-main/src/ui/tabs/search/mod.rs +++ b/rm-main/src/tui/ui/tabs/search/mod.rs @@ -19,11 +19,13 @@ use tokio::sync::mpsc::{self, UnboundedSender}; use tui_input::Input; use crate::{ - app, transmission::TorrentAction, - ui::{ - components::{table::GenericTable, Component, ComponentAction}, - to_input_request, + tui::{ + app, + ui::{ + components::{table::GenericTable, Component, ComponentAction}, + to_input_request, + }, }, }; use rm_shared::{ diff --git a/rm-main/src/ui/tabs/search/popups/mod.rs b/rm-main/src/tui/ui/tabs/search/popups/mod.rs similarity index 93% rename from rm-main/src/ui/tabs/search/popups/mod.rs rename to rm-main/src/tui/ui/tabs/search/popups/mod.rs index 443ff05..c11fe8f 100644 --- a/rm-main/src/ui/tabs/search/popups/mod.rs +++ b/rm-main/src/tui/ui/tabs/search/popups/mod.rs @@ -5,10 +5,9 @@ use ratatui::prelude::*; use ratatui::Frame; use rm_shared::action::Action; -use crate::{ - app, - ui::components::{Component, ComponentAction}, -}; +use crate::tui::app; +use crate::tui::ui::components::Component; +use crate::tui::ui::components::ComponentAction; use super::ConfiguredProvider; diff --git a/rm-main/src/ui/tabs/search/popups/providers.rs b/rm-main/src/tui/ui/tabs/search/popups/providers.rs similarity index 99% rename from rm-main/src/ui/tabs/search/popups/providers.rs rename to rm-main/src/tui/ui/tabs/search/popups/providers.rs index 3602c64..9df1855 100644 --- a/rm-main/src/ui/tabs/search/popups/providers.rs +++ b/rm-main/src/tui/ui/tabs/search/popups/providers.rs @@ -13,7 +13,7 @@ use ratatui::{ use rm_config::CONFIG; use rm_shared::action::Action; -use crate::ui::{ +use crate::tui::ui::{ centered_rect, components::{Component, ComponentAction}, tabs::search::{ConfiguredProvider, ProviderState}, diff --git a/rm-main/src/ui/tabs/torrents/bottom_stats.rs b/rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs similarity index 98% rename from rm-main/src/ui/tabs/torrents/bottom_stats.rs rename to rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs index 6597f64..6a4fe01 100644 --- a/rm-main/src/ui/tabs/torrents/bottom_stats.rs +++ b/rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs @@ -8,7 +8,7 @@ use ratatui::{ use rm_shared::utils::bytes_to_human_format; use transmission_rpc::types::{FreeSpace, SessionStats}; -use crate::ui::components::Component; +use crate::tui::ui::components::Component; use super::table_manager::TableManager; diff --git a/rm-main/src/ui/tabs/torrents/input_manager.rs b/rm-main/src/tui/ui/tabs/torrents/input_manager.rs similarity index 97% rename from rm-main/src/ui/tabs/torrents/input_manager.rs rename to rm-main/src/tui/ui/tabs/torrents/input_manager.rs index 3e75f5b..5f8f20a 100644 --- a/rm-main/src/ui/tabs/torrents/input_manager.rs +++ b/rm-main/src/tui/ui/tabs/torrents/input_manager.rs @@ -5,7 +5,7 @@ use ratatui::{ use rm_config::CONFIG; use tui_input::{Input, InputRequest}; -use crate::ui::components::Component; +use crate::tui::ui::components::Component; pub struct InputManager { input: Input, diff --git a/rm-main/src/ui/tabs/torrents/mod.rs b/rm-main/src/tui/ui/tabs/torrents/mod.rs similarity index 98% rename from rm-main/src/ui/tabs/torrents/mod.rs rename to rm-main/src/tui/ui/tabs/torrents/mod.rs index 60ee6c1..7e2c699 100644 --- a/rm-main/src/ui/tabs/torrents/mod.rs +++ b/rm-main/src/tui/ui/tabs/torrents/mod.rs @@ -7,8 +7,10 @@ pub mod task_manager; pub mod tasks; use crate::transmission::TorrentAction; -use crate::ui::tabs::torrents::popups::stats::StatisticsPopup; +use crate::tui::app; +use crate::tui::ui::components::{Component, ComponentAction}; +use popups::stats::StatisticsPopup; use ratatui::prelude::*; use ratatui::widgets::{Row, Table}; use rm_config::CONFIG; @@ -16,8 +18,7 @@ use rm_shared::status_task::StatusTask; use rustmission_torrent::RustmissionTorrent; use transmission_rpc::types::TorrentStatus; -use crate::ui::components::{Component, ComponentAction}; -use crate::{app, transmission}; +use crate::transmission; use rm_shared::action::{Action, ErrorMessage, UpdateAction}; use self::bottom_stats::BottomStats; diff --git a/rm-main/src/ui/tabs/torrents/popups/files.rs b/rm-main/src/tui/ui/tabs/torrents/popups/files.rs similarity index 99% rename from rm-main/src/ui/tabs/torrents/popups/files.rs rename to rm-main/src/tui/ui/tabs/torrents/popups/files.rs index 520d429..cc29998 100644 --- a/rm-main/src/ui/tabs/torrents/popups/files.rs +++ b/rm-main/src/tui/ui/tabs/torrents/popups/files.rs @@ -14,11 +14,13 @@ use transmission_rpc::types::{Id, Torrent, TorrentSetArgs}; use tui_tree_widget::{Tree, TreeItem, TreeState}; use crate::{ - app, transmission::TorrentAction, - ui::{ - centered_rect, - components::{Component, ComponentAction}, + tui::{ + app, + ui::{ + centered_rect, + components::{Component, ComponentAction}, + }, }, }; use rm_shared::{ diff --git a/rm-main/src/ui/tabs/torrents/popups/mod.rs b/rm-main/src/tui/ui/tabs/torrents/popups/mod.rs similarity index 99% rename from rm-main/src/ui/tabs/torrents/popups/mod.rs rename to rm-main/src/tui/ui/tabs/torrents/popups/mod.rs index cda27f8..ee68e87 100644 --- a/rm-main/src/ui/tabs/torrents/popups/mod.rs +++ b/rm-main/src/tui/ui/tabs/torrents/popups/mod.rs @@ -1,8 +1,9 @@ -use self::{files::FilesPopup, stats::StatisticsPopup}; -use crate::{ +use crate::tui::{ app, ui::components::{Component, ComponentAction}, }; + +use self::{files::FilesPopup, stats::StatisticsPopup}; use rm_shared::action::{Action, UpdateAction}; use ratatui::prelude::*; diff --git a/rm-main/src/ui/tabs/torrents/popups/stats.rs b/rm-main/src/tui/ui/tabs/torrents/popups/stats.rs similarity index 98% rename from rm-main/src/ui/tabs/torrents/popups/stats.rs rename to rm-main/src/tui/ui/tabs/torrents/popups/stats.rs index f301c74..2df6052 100644 --- a/rm-main/src/ui/tabs/torrents/popups/stats.rs +++ b/rm-main/src/tui/ui/tabs/torrents/popups/stats.rs @@ -11,11 +11,12 @@ use ratatui::{ use rm_config::CONFIG; use transmission_rpc::types::SessionStats; -use crate::ui::{ +use rm_shared::{action::Action, utils::bytes_to_human_format}; + +use crate::tui::ui::{ centered_rect, components::{Component, ComponentAction}, }; -use rm_shared::{action::Action, utils::bytes_to_human_format}; pub struct StatisticsPopup { stats: Arc, diff --git a/rm-main/src/ui/tabs/torrents/rustmission_torrent.rs b/rm-main/src/tui/ui/tabs/torrents/rustmission_torrent.rs similarity index 100% rename from rm-main/src/ui/tabs/torrents/rustmission_torrent.rs rename to rm-main/src/tui/ui/tabs/torrents/rustmission_torrent.rs diff --git a/rm-main/src/ui/tabs/torrents/table_manager.rs b/rm-main/src/tui/ui/tabs/torrents/table_manager.rs similarity index 99% rename from rm-main/src/ui/tabs/torrents/table_manager.rs rename to rm-main/src/tui/ui/tabs/torrents/table_manager.rs index 72d6a73..f868cee 100644 --- a/rm-main/src/ui/tabs/torrents/table_manager.rs +++ b/rm-main/src/tui/ui/tabs/torrents/table_manager.rs @@ -4,7 +4,7 @@ use rm_config::CONFIG; use rm_shared::header::Header; use std::collections::HashMap; -use crate::ui::components::table::GenericTable; +use crate::tui::ui::components::table::GenericTable; use super::rustmission_torrent::RustmissionTorrent; diff --git a/rm-main/src/ui/tabs/torrents/task_manager.rs b/rm-main/src/tui/ui/tabs/torrents/task_manager.rs similarity index 99% rename from rm-main/src/ui/tabs/torrents/task_manager.rs rename to rm-main/src/tui/ui/tabs/torrents/task_manager.rs index 4e4d24f..6a64515 100644 --- a/rm-main/src/ui/tabs/torrents/task_manager.rs +++ b/rm-main/src/tui/ui/tabs/torrents/task_manager.rs @@ -2,15 +2,16 @@ use ratatui::prelude::*; use throbber_widgets_tui::ThrobberState; use tokio::time::Instant; -use crate::{ - app, - ui::components::{Component, ComponentAction}, -}; use rm_shared::{ action::{Action, UpdateAction}, status_task::StatusTask, }; +use crate::tui::{ + app, + ui::components::{Component, ComponentAction}, +}; + use super::{ rustmission_torrent::RustmissionTorrent, table_manager::Filter, diff --git a/rm-main/src/ui/tabs/torrents/tasks/add_magnet.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs similarity index 94% rename from rm-main/src/ui/tabs/torrents/tasks/add_magnet.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs index d2d07f0..7e38c09 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/add_magnet.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs @@ -2,12 +2,14 @@ use crossterm::event::{KeyCode, KeyEvent}; use ratatui::prelude::*; use crate::{ - app, transmission::TorrentAction, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, - to_input_request, + tui::{ + app, + ui::{ + components::{Component, ComponentAction}, + tabs::torrents::input_manager::InputManager, + to_input_request, + }, }, }; use rm_shared::{ diff --git a/rm-main/src/ui/tabs/torrents/tasks/default.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/default.rs similarity index 92% rename from rm-main/src/ui/tabs/torrents/tasks/default.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/default.rs index 03013d4..2209fc5 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/default.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/default.rs @@ -1,8 +1,8 @@ -use crate::ui::components::Component; - use ratatui::prelude::*; use rm_config::CONFIG; +use crate::tui::ui::components::Component; + pub struct DefaultBar {} impl DefaultBar { diff --git a/rm-main/src/ui/tabs/torrents/tasks/delete_torrent.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs similarity index 92% rename from rm-main/src/ui/tabs/torrents/tasks/delete_torrent.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs index 3544820..844f68c 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/delete_torrent.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs @@ -2,15 +2,11 @@ use crossterm::event::KeyCode; use ratatui::prelude::*; use transmission_rpc::types::Id; -use crate::{ - app, - transmission::TorrentAction, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, - to_input_request, - }, -}; +use crate::transmission::TorrentAction; +use crate::tui::app; +use crate::tui::ui::components::{Component, ComponentAction}; +use crate::tui::ui::tabs::torrents::input_manager::InputManager; +use crate::tui::ui::to_input_request; use rm_shared::action::{Action, UpdateAction}; use rm_shared::status_task::StatusTask; diff --git a/rm-main/src/ui/tabs/torrents/tasks/filter.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs similarity index 98% rename from rm-main/src/ui/tabs/torrents/tasks/filter.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs index c0e1848..b3e697b 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/filter.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs @@ -1,7 +1,9 @@ use crossterm::event::KeyCode; use ratatui::prelude::*; -use crate::{ +use rm_shared::action::{Action, UpdateAction}; + +use crate::tui::{ app, ui::{ components::{Component, ComponentAction}, @@ -9,7 +11,6 @@ use crate::{ to_input_request, }, }; -use rm_shared::action::{Action, UpdateAction}; pub struct FilterBar { ctx: app::Ctx, diff --git a/rm-main/src/ui/tabs/torrents/tasks/mod.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/mod.rs similarity index 100% rename from rm-main/src/ui/tabs/torrents/tasks/mod.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/mod.rs diff --git a/rm-main/src/ui/tabs/torrents/tasks/move_torrent.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs similarity index 90% rename from rm-main/src/ui/tabs/torrents/tasks/move_torrent.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs index e7febce..9f6a2b1 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/move_torrent.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs @@ -7,12 +7,14 @@ use rm_shared::{ use transmission_rpc::types::Id; use crate::{ - app, transmission::TorrentAction, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, - to_input_request, + tui::{ + app, + ui::{ + components::{Component, ComponentAction}, + tabs::torrents::input_manager::InputManager, + to_input_request, + }, }, }; diff --git a/rm-main/src/ui/tabs/torrents/tasks/status.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/status.rs similarity index 98% rename from rm-main/src/ui/tabs/torrents/tasks/status.rs rename to rm-main/src/tui/ui/tabs/torrents/tasks/status.rs index bee0178..bdf3849 100644 --- a/rm-main/src/ui/tabs/torrents/tasks/status.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/status.rs @@ -1,5 +1,3 @@ -use crate::{app, ui::components::Component}; - use ratatui::{prelude::*, style::Style}; use rm_shared::{ action::{Action, UpdateAction}, @@ -8,6 +6,8 @@ use rm_shared::{ use throbber_widgets_tui::ThrobberState; use tokio::time::{self, Instant}; +use crate::tui::{app, ui::components::Component}; + pub struct StatusBar { task: StatusTask, pub task_status: CurrentTaskState, From a5f00372c818104d664693b9300a23d0885ccb80 Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 16:05:47 +0200 Subject: [PATCH 2/6] split cli commands --- rm-main/src/cli/add_torrent.rs | 46 ++++++++++++++++++ rm-main/src/cli/fetch_rss.rs | 42 ++++++++++++++++ rm-main/src/cli/mod.rs | 87 ++-------------------------------- 3 files changed, 93 insertions(+), 82 deletions(-) create mode 100644 rm-main/src/cli/add_torrent.rs create mode 100644 rm-main/src/cli/fetch_rss.rs diff --git a/rm-main/src/cli/add_torrent.rs b/rm-main/src/cli/add_torrent.rs new file mode 100644 index 0000000..a6eb416 --- /dev/null +++ b/rm-main/src/cli/add_torrent.rs @@ -0,0 +1,46 @@ +use std::{fs::File, io::Read}; + +use anyhow::Result; +use base64::Engine; +use transmission_rpc::types::TorrentAddArgs; + +use crate::transmission; + +pub(super) async fn add_torrent(torrent: String) -> Result<()> { + let mut transclient = transmission::utils::new_client(); + let args = { + if torrent.starts_with("magnet:") + || torrent.starts_with("http:") + || torrent.starts_with("https:") + { + TorrentAddArgs { + filename: Some(torrent), + ..Default::default() + } + } else if torrent.starts_with("www") { + TorrentAddArgs { + filename: Some(format!("https://{torrent}")), + ..Default::default() + } + } else { + let mut torrent_file = File::open(torrent)?; + let mut buf = vec![]; + torrent_file.read_to_end(&mut buf).unwrap(); + let metainfo = base64::engine::general_purpose::STANDARD.encode(buf); + TorrentAddArgs { + metainfo: Some(metainfo), + ..Default::default() + } + } + }; + + if let Err(e) = transclient.torrent_add(args).await { + eprintln!("error while adding a torrent: {e}"); + if e.to_string().contains("expected value at line") { + eprintln!("Check whether your arguments are valid."); + } + + std::process::exit(1); + }; + Ok(()) +} diff --git a/rm-main/src/cli/fetch_rss.rs b/rm-main/src/cli/fetch_rss.rs new file mode 100644 index 0000000..4122035 --- /dev/null +++ b/rm-main/src/cli/fetch_rss.rs @@ -0,0 +1,42 @@ +use anyhow::{bail, Result}; +use regex::Regex; +use transmission_rpc::types::TorrentAddArgs; + +use crate::transmission; + +pub async fn fetch_rss(url: &str, filter: Option<&str>) -> Result<()> { + let mut transclient = transmission::utils::new_client(); + let content = reqwest::get(url).await?.bytes().await?; + let channel = rss::Channel::read_from(&content[..])?; + let re: Option = { + if let Some(filter_str) = filter { + let res = Regex::new(filter_str)?; + Some(res) + } else { + None + } + }; + let items = channel.items().iter().filter_map(|item| { + if let (Some(title), Some(url)) = (item.title(), item.link()) { + if let Some(re) = &re { + if re.is_match(title) { + return Some((title, url)); + } + } else { + return Some((title, url)); + } + } + None + }); + for (title, url) in items { + println!("downloading {title}"); + let args = TorrentAddArgs { + filename: Some(url.to_string()), + ..Default::default() + }; + if let Err(e) = transclient.torrent_add(args).await { + bail!("error while adding a torrent: {e}") + } + } + Ok(()) +} diff --git a/rm-main/src/cli/mod.rs b/rm-main/src/cli/mod.rs index 7f17a54..cdd3e5e 100644 --- a/rm-main/src/cli/mod.rs +++ b/rm-main/src/cli/mod.rs @@ -1,12 +1,11 @@ -use std::{fs::File, io::Read}; +mod add_torrent; +mod fetch_rss; -use anyhow::{bail, Result}; -use base64::Engine; +use anyhow::Result; use clap::{Parser, Subcommand}; -use regex::Regex; -use transmission_rpc::types::TorrentAddArgs; -use crate::transmission; +use add_torrent::add_torrent; +use fetch_rss::fetch_rss; #[derive(Parser)] #[command(version, about)] @@ -28,79 +27,3 @@ pub async fn handle_command(command: Commands) -> Result<()> { } Ok(()) } - -async fn add_torrent(torrent: String) -> Result<()> { - let mut transclient = transmission::utils::new_client(); - let args = { - if torrent.starts_with("magnet:") - || torrent.starts_with("http:") - || torrent.starts_with("https:") - { - TorrentAddArgs { - filename: Some(torrent), - ..Default::default() - } - } else if torrent.starts_with("www") { - TorrentAddArgs { - filename: Some(format!("https://{torrent}")), - ..Default::default() - } - } else { - let mut torrent_file = File::open(torrent)?; - let mut buf = vec![]; - torrent_file.read_to_end(&mut buf).unwrap(); - let metainfo = base64::engine::general_purpose::STANDARD.encode(buf); - TorrentAddArgs { - metainfo: Some(metainfo), - ..Default::default() - } - } - }; - - if let Err(e) = transclient.torrent_add(args).await { - eprintln!("error while adding a torrent: {e}"); - if e.to_string().contains("expected value at line") { - eprintln!("Check whether your arguments are valid."); - } - - std::process::exit(1); - }; - Ok(()) -} - -async fn fetch_rss(url: &str, filter: Option<&str>) -> Result<()> { - let mut transclient = transmission::utils::new_client(); - let content = reqwest::get(url).await?.bytes().await?; - let channel = rss::Channel::read_from(&content[..])?; - let re: Option = { - if let Some(filter_str) = filter { - let res = Regex::new(filter_str)?; - Some(res) - } else { - None - } - }; - let items = channel.items().iter().filter_map(|item| { - if let (Some(title), Some(url)) = (item.title(), item.link()) { - if let Some(re) = &re { - if re.is_match(title) { - return Some((title, url)); - } - } else { - return Some((title, url)); - } - } - None - }); - for (title, url) in items { - println!("downloading {title}"); - let args = TorrentAddArgs { - filename: Some(url.to_string()), - ..Default::default() - }; - if let Err(e) = transclient.torrent_add(args).await { - bail!("error while adding a torrent: {e}") - } - } - Ok(()) -} From 64f8519b3d9995e7ac4dd41fdae9106cb0dc8287 Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 17:14:47 +0200 Subject: [PATCH 3/6] various code cleanups --- rm-main/src/tui/mod.rs | 67 ++++++++----------- rm-main/src/tui/ui/global_popups/help.rs | 11 ++- rm-main/src/tui/ui/mod.rs | 24 +++---- rm-main/src/tui/ui/tabs/search/mod.rs | 14 ++-- .../src/tui/ui/tabs/torrents/input_manager.rs | 13 +++- .../tui/ui/tabs/torrents/tasks/add_magnet.rs | 26 +++---- .../ui/tabs/torrents/tasks/delete_torrent.rs | 4 +- .../src/tui/ui/tabs/torrents/tasks/filter.rs | 13 ++-- .../ui/tabs/torrents/tasks/move_torrent.rs | 19 ++---- 9 files changed, 82 insertions(+), 109 deletions(-) diff --git a/rm-main/src/tui/mod.rs b/rm-main/src/tui/mod.rs index c2eecce..334a5b2 100644 --- a/rm-main/src/tui/mod.rs +++ b/rm-main/src/tui/mod.rs @@ -10,7 +10,7 @@ use crossterm::{ terminal::{EnterAlternateScreen, LeaveAlternateScreen}, }; use futures::{FutureExt, StreamExt}; -use ratatui::backend::CrosstermBackend as Backend; +use ratatui::{backend::CrosstermBackend as Backend, Terminal}; use tokio::{ sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, task::JoinHandle, @@ -18,7 +18,7 @@ use tokio::{ use tokio_util::sync::CancellationToken; pub struct Tui { - pub terminal: ratatui::Terminal>, + pub terminal: Terminal>, pub task: JoinHandle>, pub cancellation_token: CancellationToken, pub event_rx: UnboundedReceiver, @@ -27,7 +27,7 @@ pub struct Tui { impl Tui { pub(crate) fn new() -> Result { - let terminal = ratatui::Terminal::new(Backend::new(std::io::stdout()))?; + let terminal = Terminal::new(Backend::new(std::io::stdout()))?; let (event_tx, event_rx) = mpsc::unbounded_channel(); let cancellation_token = CancellationToken::new(); let task = tokio::spawn(async { Ok(()) }); @@ -40,8 +40,31 @@ impl Tui { }) } + fn handle_crossterm_event( + event: Option>, + event_tx: &UnboundedSender, + ) -> Result<()> { + match event { + Some(Ok(Event::Key(key))) => { + if key.kind == KeyEventKind::Press { + event_tx.send(Event::Key(key)).unwrap(); + } + } + Some(Ok(Event::Resize(x, y))) => event_tx.send(Event::Resize(x, y)).unwrap(), + Some(Err(e)) => Err(e)?, + _ => (), + } + Ok(()) + } + + pub(crate) fn enter(&mut self) -> Result<()> { + crossterm::terminal::enable_raw_mode()?; + crossterm::execute!(std::io::stdout(), EnterAlternateScreen, cursor::Hide)?; + self.start()?; + Ok(()) + } + pub fn start(&mut self) -> Result<()> { - self.cancel(); self.cancellation_token = CancellationToken::new(); let cancellation_token = self.cancellation_token.clone(); let event_tx = self.event_tx.clone(); @@ -60,25 +83,8 @@ impl Tui { Ok(()) } - fn handle_crossterm_event( - event: Option>, - event_tx: &UnboundedSender, - ) -> Result<()> { - match event { - Some(Ok(Event::Key(key))) => { - if key.kind == KeyEventKind::Press { - event_tx.send(Event::Key(key)).unwrap(); - } - } - Some(Ok(Event::Resize(x, y))) => event_tx.send(Event::Resize(x, y)).unwrap(), - Some(Err(e)) => Err(e)?, - _ => (), - } - Ok(()) - } - - pub(crate) fn stop(&self) { - self.cancel(); + pub(crate) fn exit(&mut self) -> Result<()> { + self.cancellation_token.cancel(); let mut counter = 0; while !self.task.is_finished() { std::thread::sleep(Duration::from_millis(1)); @@ -90,17 +96,6 @@ impl Tui { break; } } - } - - pub(crate) fn enter(&mut self) -> Result<()> { - crossterm::terminal::enable_raw_mode()?; - crossterm::execute!(std::io::stdout(), EnterAlternateScreen, cursor::Hide)?; - self.start()?; - Ok(()) - } - - pub(crate) fn exit(&mut self) -> Result<()> { - self.stop(); if crossterm::terminal::is_raw_mode_enabled()? { self.terminal.flush()?; crossterm::execute!(std::io::stdout(), LeaveAlternateScreen, cursor::Show)?; @@ -109,10 +104,6 @@ impl Tui { Ok(()) } - pub fn cancel(&self) { - self.cancellation_token.cancel(); - } - pub async fn next(&mut self) -> Option { self.event_rx.recv().await } diff --git a/rm-main/src/tui/ui/global_popups/help.rs b/rm-main/src/tui/ui/global_popups/help.rs index a992b7f..76ff921 100644 --- a/rm-main/src/tui/ui/global_popups/help.rs +++ b/rm-main/src/tui/ui/global_popups/help.rs @@ -80,14 +80,13 @@ impl HelpPopup { .push(keybinding.keycode_string()); } - for (_, keycodes) in &keys { - let delimiter_len; + for keycodes in keys.values() { let mut keycodes_total_len = 0; - if keycodes.len() >= 2 { - delimiter_len = (keycodes.len() - 1) * 3; + let delimiter_len = if keycodes.len() >= 2 { + (keycodes.len() - 1) * 3 } else { - delimiter_len = 0; - } + 0 + }; for keycode in keycodes { keycodes_total_len += keycode.chars().count(); diff --git a/rm-main/src/tui/ui/mod.rs b/rm-main/src/tui/ui/mod.rs index 56648c7..9b8c3fa 100644 --- a/rm-main/src/tui/ui/mod.rs +++ b/rm-main/src/tui/ui/mod.rs @@ -3,11 +3,9 @@ pub mod global_popups; pub mod tabs; use components::ComponentAction; -use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use global_popups::ErrorPopup; use ratatui::prelude::*; use tabs::torrents::TorrentsTab; -use tui_input::InputRequest; use rm_shared::action::{Action, UpdateAction}; @@ -99,17 +97,17 @@ impl Component for MainWindow { } } -const fn to_input_request(key_event: KeyEvent) -> Option { - use InputRequest as R; - - match (key_event.code, key_event.modifiers) { - (KeyCode::Backspace, KeyModifiers::ALT) => Some(R::DeletePrevWord), - (KeyCode::Backspace, _) => Some(R::DeletePrevChar), - (KeyCode::Delete, _) => Some(R::DeleteNextChar), - (KeyCode::Char(char), _) => Some(R::InsertChar(char)), - _ => None, - } -} +// const fn to_input_request(key_event: KeyEvent) -> Option { +// use InputRequest as R; + +// match (key_event.code, key_event.modifiers) { +// (KeyCode::Backspace, KeyModifiers::ALT) => Some(R::DeletePrevWord), +// (KeyCode::Backspace, _) => Some(R::DeletePrevChar), +// (KeyCode::Delete, _) => Some(R::DeleteNextChar), +// (KeyCode::Char(char), _) => Some(R::InsertChar(char)), +// _ => None, +// } +// } fn centered_rect(r: Rect, percent_x: u16, percent_y: u16) -> Rect { let popup_layout = Layout::vertical([ diff --git a/rm-main/src/tui/ui/tabs/search/mod.rs b/rm-main/src/tui/ui/tabs/search/mod.rs index 921bc09..d90cbe7 100644 --- a/rm-main/src/tui/ui/tabs/search/mod.rs +++ b/rm-main/src/tui/ui/tabs/search/mod.rs @@ -4,7 +4,7 @@ mod popups; use std::{borrow::Cow, sync::Arc}; use bottom_bar::BottomBar; -use crossterm::event::{KeyCode, KeyEvent}; +use crossterm::event::{Event, KeyCode, KeyEvent}; use futures::{stream::FuturesUnordered, StreamExt}; use magnetease::{Magnet, MagneteaseErrorKind, WhichProvider}; use popups::{CurrentPopup, PopupManager}; @@ -16,16 +16,13 @@ use ratatui::{ use reqwest::Client; use rm_config::CONFIG; use tokio::sync::mpsc::{self, UnboundedSender}; -use tui_input::Input; +use tui_input::{backend::crossterm::to_input_request, Input}; use crate::{ transmission::TorrentAction, tui::{ app, - ui::{ - components::{table::GenericTable, Component, ComponentAction}, - to_input_request, - }, + ui::components::{table::GenericTable, Component, ComponentAction}, }, }; use rm_shared::{ @@ -59,7 +56,7 @@ impl SearchTab { let mut configured_providers = vec![]; for provider in WhichProvider::all() { - configured_providers.push(ConfiguredProvider::new(provider.clone(), false)); + configured_providers.push(ConfiguredProvider::new(provider, false)); } for configured_provider in &mut configured_providers { @@ -156,7 +153,8 @@ impl SearchTab { .send_update_action(UpdateAction::SwitchToNormalMode); } _ => { - if let Some(req) = to_input_request(input) { + let event = Event::Key(input); + if let Some(req) = to_input_request(&event) { self.input.handle(req); self.ctx.send_action(A::Render); } diff --git a/rm-main/src/tui/ui/tabs/torrents/input_manager.rs b/rm-main/src/tui/ui/tabs/torrents/input_manager.rs index 5f8f20a..1865ec5 100644 --- a/rm-main/src/tui/ui/tabs/torrents/input_manager.rs +++ b/rm-main/src/tui/ui/tabs/torrents/input_manager.rs @@ -1,9 +1,10 @@ +use crossterm::event::{Event, KeyEvent}; use ratatui::{ prelude::*, widgets::{Clear, Paragraph}, }; use rm_config::CONFIG; -use tui_input::{Input, InputRequest}; +use tui_input::{backend::crossterm::to_input_request, Input, InputResponse}; use crate::tui::ui::components::Component; @@ -31,8 +32,14 @@ impl InputManager { self.input.to_string() } - pub fn handle(&mut self, req: InputRequest) { - self.input.handle(req); + pub fn handle_key(&mut self, key: KeyEvent) -> InputResponse { + let event = Event::Key(key); + + if let Some(req) = to_input_request(&event) { + self.input.handle(req) + } else { + None + } } } diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs index 7e38c09..906bd6b 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs @@ -8,7 +8,6 @@ use crate::{ ui::{ components::{Component, ComponentAction}, tabs::torrents::input_manager::InputManager, - to_input_request, }, }, }; @@ -60,10 +59,8 @@ impl AddMagnetBar { return ComponentAction::Quit; } - if let Some(req) = to_input_request(input) { - self.input_magnet_mgr.handle(req); + if let Some(_) = self.input_magnet_mgr.handle_key(input) { self.ctx.send_action(Action::Render); - return ComponentAction::Nothing; } ComponentAction::Nothing @@ -80,22 +77,15 @@ impl AddMagnetBar { let task = StatusTask::new_add(self.input_magnet_mgr.text()); self.ctx.send_update_action(UpdateAction::TaskSet(task)); - let update_action = UpdateAction::SwitchToNormalMode; - self.ctx.send_update_action(update_action); - - return ComponentAction::Quit; - } - if input.code == KeyCode::Esc { - return ComponentAction::Quit; - } - - if let Some(req) = to_input_request(input) { - self.input_location_mgr.handle(req); + ComponentAction::Quit + } else if input.code == KeyCode::Esc { + ComponentAction::Quit + } else if self.input_location_mgr.handle_key(input).is_some() { self.ctx.send_action(Action::Render); - return ComponentAction::Nothing; + ComponentAction::Nothing + } else { + ComponentAction::Nothing } - - ComponentAction::Nothing } } diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs index 844f68c..4b5204c 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs @@ -6,7 +6,6 @@ use crate::transmission::TorrentAction; use crate::tui::app; use crate::tui::ui::components::{Component, ComponentAction}; use crate::tui::ui::tabs::torrents::input_manager::InputManager; -use crate::tui::ui::to_input_request; use rm_shared::action::{Action, UpdateAction}; use rm_shared::status_task::StatusTask; @@ -81,8 +80,7 @@ impl Component for DeleteBar { } } - if let Some(req) = to_input_request(input) { - self.input_mgr.handle(req); + if let Some(_) = self.input_mgr.handle_key(input) { self.ctx.send_action(Action::Render); } diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs index b3e697b..1b42129 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs @@ -8,7 +8,6 @@ use crate::tui::{ ui::{ components::{Component, ComponentAction}, tabs::torrents::{input_manager::InputManager, table_manager::Filter}, - to_input_request, }, }; @@ -40,16 +39,14 @@ impl Component for FilterBar { if self.input.text().is_empty() { self.ctx.send_update_action(UpdateAction::SearchFilterClear); } - return ComponentAction::Quit; - } - - if let Some(req) = to_input_request(input) { - self.input.handle(req); + ComponentAction::Quit + } else if self.input.handle_key(input).is_some() { self.ctx .send_update_action(UpdateAction::SearchFilterApply(self.input.text())); + ComponentAction::Nothing + } else { + ComponentAction::Nothing } - - ComponentAction::Nothing } _ => ComponentAction::Nothing, } diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs b/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs index 9f6a2b1..d84537a 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs +++ b/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs @@ -13,7 +13,6 @@ use crate::{ ui::{ components::{Component, ComponentAction}, tabs::torrents::input_manager::InputManager, - to_input_request, }, }, }; @@ -46,19 +45,15 @@ impl MoveBar { let task = StatusTask::new_move(new_location); self.ctx.send_update_action(UpdateAction::TaskSet(task)); - return ComponentAction::Quit; - } - - if input.code == KeyCode::Esc { - return ComponentAction::Quit; - } - - if let Some(req) = to_input_request(input) { - self.input_mgr.handle(req); + ComponentAction::Quit + } else if input.code == KeyCode::Esc { + ComponentAction::Quit + } else if self.input_mgr.handle_key(input).is_some() { self.ctx.send_action(Action::Render); + ComponentAction::Nothing + } else { + ComponentAction::Nothing } - - ComponentAction::Nothing } } From 677ce786e87166c37a5b1f03026b0b8074add099 Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 17:17:54 +0200 Subject: [PATCH 4/6] remove commented code --- rm-main/src/tui/ui/mod.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/rm-main/src/tui/ui/mod.rs b/rm-main/src/tui/ui/mod.rs index 9b8c3fa..b47e380 100644 --- a/rm-main/src/tui/ui/mod.rs +++ b/rm-main/src/tui/ui/mod.rs @@ -97,18 +97,6 @@ impl Component for MainWindow { } } -// const fn to_input_request(key_event: KeyEvent) -> Option { -// use InputRequest as R; - -// match (key_event.code, key_event.modifiers) { -// (KeyCode::Backspace, KeyModifiers::ALT) => Some(R::DeletePrevWord), -// (KeyCode::Backspace, _) => Some(R::DeletePrevChar), -// (KeyCode::Delete, _) => Some(R::DeleteNextChar), -// (KeyCode::Char(char), _) => Some(R::InsertChar(char)), -// _ => None, -// } -// } - fn centered_rect(r: Rect, percent_x: u16, percent_y: u16) -> Rect { let popup_layout = Layout::vertical([ Constraint::Percentage((100 - percent_y) / 2), From 443acf31bd426dd244848a89e9a65c0898cf248c Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 17:41:11 +0200 Subject: [PATCH 5/6] restructure the project better --- rm-main/src/tui/app.rs | 6 +- rm-main/src/tui/{ui => }/components/mod.rs | 1 - rm-main/src/tui/{ui => }/components/table.rs | 0 rm-main/src/tui/{ui => }/components/tabs.rs | 0 .../src/tui/{ui => }/global_popups/error.rs | 4 +- .../src/tui/{ui => }/global_popups/help.rs | 6 +- rm-main/src/tui/{ui => }/global_popups/mod.rs | 0 rm-main/src/tui/{ui/mod.rs => main_window.rs} | 22 ++-- rm-main/src/tui/mod.rs | 114 +----------------- rm-main/src/tui/{ui => }/tabs/mod.rs | 0 .../tui/{ui => }/tabs/search/bottom_bar.rs | 2 +- rm-main/src/tui/{ui => }/tabs/search/mod.rs | 2 +- .../tui/{ui => }/tabs/search/popups/mod.rs | 4 +- .../{ui => }/tabs/search/popups/providers.rs | 4 +- .../{ui => }/tabs/torrents/bottom_stats.rs | 2 +- .../{ui => }/tabs/torrents/input_manager.rs | 2 +- rm-main/src/tui/{ui => }/tabs/torrents/mod.rs | 2 +- .../{ui => }/tabs/torrents/popups/files.rs | 6 +- .../tui/{ui => }/tabs/torrents/popups/mod.rs | 2 +- .../{ui => }/tabs/torrents/popups/stats.rs | 4 +- .../tabs/torrents/rustmission_torrent.rs | 0 .../{ui => }/tabs/torrents/table_manager.rs | 2 +- .../{ui => }/tabs/torrents/task_manager.rs | 2 +- .../tabs/torrents/tasks/add_magnet.rs | 6 +- .../{ui => }/tabs/torrents/tasks/default.rs | 2 +- .../tabs/torrents/tasks/delete_torrent.rs | 4 +- .../{ui => }/tabs/torrents/tasks/filter.rs | 6 +- .../tui/{ui => }/tabs/torrents/tasks/mod.rs | 0 .../tabs/torrents/tasks/move_torrent.rs | 6 +- .../{ui => }/tabs/torrents/tasks/status.rs | 2 +- rm-main/src/tui/terminal.rs | 107 ++++++++++++++++ 31 files changed, 152 insertions(+), 168 deletions(-) rename rm-main/src/tui/{ui => }/components/mod.rs (95%) rename rm-main/src/tui/{ui => }/components/table.rs (100%) rename rm-main/src/tui/{ui => }/components/tabs.rs (100%) rename rm-main/src/tui/{ui => }/global_popups/error.rs (97%) rename rm-main/src/tui/{ui => }/global_popups/help.rs (98%) rename rm-main/src/tui/{ui => }/global_popups/mod.rs (100%) rename rm-main/src/tui/{ui/mod.rs => main_window.rs} (89%) rename rm-main/src/tui/{ui => }/tabs/mod.rs (100%) rename rm-main/src/tui/{ui => }/tabs/search/bottom_bar.rs (98%) rename rm-main/src/tui/{ui => }/tabs/search/mod.rs (99%) rename rm-main/src/tui/{ui => }/tabs/search/popups/mod.rs (94%) rename rm-main/src/tui/{ui => }/tabs/search/popups/providers.rs (98%) rename rm-main/src/tui/{ui => }/tabs/torrents/bottom_stats.rs (98%) rename rm-main/src/tui/{ui => }/tabs/torrents/input_manager.rs (97%) rename rm-main/src/tui/{ui => }/tabs/torrents/mod.rs (99%) rename rm-main/src/tui/{ui => }/tabs/torrents/popups/files.rs (99%) rename rm-main/src/tui/{ui => }/tabs/torrents/popups/mod.rs (97%) rename rm-main/src/tui/{ui => }/tabs/torrents/popups/stats.rs (97%) rename rm-main/src/tui/{ui => }/tabs/torrents/rustmission_torrent.rs (100%) rename rm-main/src/tui/{ui => }/tabs/torrents/table_manager.rs (99%) rename rm-main/src/tui/{ui => }/tabs/torrents/task_manager.rs (99%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/add_magnet.rs (95%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/default.rs (92%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/delete_torrent.rs (95%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/filter.rs (91%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/mod.rs (100%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/move_torrent.rs (93%) rename rm-main/src/tui/{ui => }/tabs/torrents/tasks/status.rs (98%) create mode 100644 rm-main/src/tui/terminal.rs diff --git a/rm-main/src/tui/app.rs b/rm-main/src/tui/app.rs index c71a41f..4e987af 100644 --- a/rm-main/src/tui/app.rs +++ b/rm-main/src/tui/app.rs @@ -1,9 +1,8 @@ use std::sync::Arc; -use crate::tui::ui::components::Component; use crate::{ transmission::{self, TorrentAction}, - tui::Tui, + tui::components::Component, }; use rm_config::CONFIG; @@ -14,8 +13,7 @@ use crossterm::event::{Event, KeyCode, KeyModifiers}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use transmission_rpc::{types::SessionGet, TransClient}; -use super::ui::components::tabs::CurrentTab; -use super::ui::MainWindow; +use super::{components::tabs::CurrentTab, main_window::MainWindow, terminal::Tui}; #[derive(Clone)] pub struct Ctx { diff --git a/rm-main/src/tui/ui/components/mod.rs b/rm-main/src/tui/components/mod.rs similarity index 95% rename from rm-main/src/tui/ui/components/mod.rs rename to rm-main/src/tui/components/mod.rs index 6e60556..a8fdd47 100644 --- a/rm-main/src/tui/ui/components/mod.rs +++ b/rm-main/src/tui/components/mod.rs @@ -6,7 +6,6 @@ use ratatui::Frame; use rm_shared::action::Action; use rm_shared::action::UpdateAction; -pub use tabs::TabComponent; #[derive(Clone, Copy, PartialEq, Eq)] pub enum ComponentAction { diff --git a/rm-main/src/tui/ui/components/table.rs b/rm-main/src/tui/components/table.rs similarity index 100% rename from rm-main/src/tui/ui/components/table.rs rename to rm-main/src/tui/components/table.rs diff --git a/rm-main/src/tui/ui/components/tabs.rs b/rm-main/src/tui/components/tabs.rs similarity index 100% rename from rm-main/src/tui/ui/components/tabs.rs rename to rm-main/src/tui/components/tabs.rs diff --git a/rm-main/src/tui/ui/global_popups/error.rs b/rm-main/src/tui/global_popups/error.rs similarity index 97% rename from rm-main/src/tui/ui/global_popups/error.rs rename to rm-main/src/tui/global_popups/error.rs index ae78082..fbd57e7 100644 --- a/rm-main/src/tui/ui/global_popups/error.rs +++ b/rm-main/src/tui/global_popups/error.rs @@ -5,9 +5,9 @@ use ratatui::{ use rm_shared::action::Action; -use crate::tui::ui::{ - centered_rect, +use crate::tui::{ components::{Component, ComponentAction}, + main_window::centered_rect, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/rm-main/src/tui/ui/global_popups/help.rs b/rm-main/src/tui/global_popups/help.rs similarity index 98% rename from rm-main/src/tui/ui/global_popups/help.rs rename to rm-main/src/tui/global_popups/help.rs index 76ff921..6bd7692 100644 --- a/rm-main/src/tui/ui/global_popups/help.rs +++ b/rm-main/src/tui/global_popups/help.rs @@ -16,10 +16,8 @@ use rm_shared::action::Action; use crate::tui::{ app, - ui::{ - centered_rect, - components::{Component, ComponentAction}, - }, + components::{Component, ComponentAction}, + main_window::centered_rect, }; macro_rules! add_line { diff --git a/rm-main/src/tui/ui/global_popups/mod.rs b/rm-main/src/tui/global_popups/mod.rs similarity index 100% rename from rm-main/src/tui/ui/global_popups/mod.rs rename to rm-main/src/tui/global_popups/mod.rs diff --git a/rm-main/src/tui/ui/mod.rs b/rm-main/src/tui/main_window.rs similarity index 89% rename from rm-main/src/tui/ui/mod.rs rename to rm-main/src/tui/main_window.rs index b47e380..1ed5a07 100644 --- a/rm-main/src/tui/ui/mod.rs +++ b/rm-main/src/tui/main_window.rs @@ -1,21 +1,15 @@ -pub mod components; -pub mod global_popups; -pub mod tabs; - -use components::ComponentAction; -use global_popups::ErrorPopup; use ratatui::prelude::*; -use tabs::torrents::TorrentsTab; use rm_shared::action::{Action, UpdateAction}; -use self::{ - components::{tabs::CurrentTab, Component, TabComponent}, - global_popups::GlobalPopupManager, - tabs::search::SearchTab, -}; +use crate::tui::components::tabs::CurrentTab; -use super::app; +use super::{ + app, + components::{tabs::TabComponent, Component, ComponentAction}, + global_popups::{ErrorPopup, GlobalPopupManager}, + tabs::{search::SearchTab, torrents::TorrentsTab}, +}; pub struct MainWindow { pub tabs: TabComponent, @@ -97,7 +91,7 @@ impl Component for MainWindow { } } -fn centered_rect(r: Rect, percent_x: u16, percent_y: u16) -> Rect { +pub fn centered_rect(r: Rect, percent_x: u16, percent_y: u16) -> Rect { let popup_layout = Layout::vertical([ Constraint::Percentage((100 - percent_y) / 2), Constraint::Percentage(percent_y), diff --git a/rm-main/src/tui/mod.rs b/rm-main/src/tui/mod.rs index 334a5b2..f10aad6 100644 --- a/rm-main/src/tui/mod.rs +++ b/rm-main/src/tui/mod.rs @@ -1,110 +1,6 @@ pub mod app; -mod ui; - -use std::{io, time::Duration}; - -use anyhow::Result; -use crossterm::{ - cursor, - event::{Event, KeyEventKind}, - terminal::{EnterAlternateScreen, LeaveAlternateScreen}, -}; -use futures::{FutureExt, StreamExt}; -use ratatui::{backend::CrosstermBackend as Backend, Terminal}; -use tokio::{ - sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, - task::JoinHandle, -}; -use tokio_util::sync::CancellationToken; - -pub struct Tui { - pub terminal: Terminal>, - pub task: JoinHandle>, - pub cancellation_token: CancellationToken, - pub event_rx: UnboundedReceiver, - pub event_tx: UnboundedSender, -} - -impl Tui { - pub(crate) fn new() -> Result { - let terminal = Terminal::new(Backend::new(std::io::stdout()))?; - let (event_tx, event_rx) = mpsc::unbounded_channel(); - let cancellation_token = CancellationToken::new(); - let task = tokio::spawn(async { Ok(()) }); - Ok(Self { - terminal, - task, - cancellation_token, - event_rx, - event_tx, - }) - } - - fn handle_crossterm_event( - event: Option>, - event_tx: &UnboundedSender, - ) -> Result<()> { - match event { - Some(Ok(Event::Key(key))) => { - if key.kind == KeyEventKind::Press { - event_tx.send(Event::Key(key)).unwrap(); - } - } - Some(Ok(Event::Resize(x, y))) => event_tx.send(Event::Resize(x, y)).unwrap(), - Some(Err(e)) => Err(e)?, - _ => (), - } - Ok(()) - } - - pub(crate) fn enter(&mut self) -> Result<()> { - crossterm::terminal::enable_raw_mode()?; - crossterm::execute!(std::io::stdout(), EnterAlternateScreen, cursor::Hide)?; - self.start()?; - Ok(()) - } - - pub fn start(&mut self) -> Result<()> { - self.cancellation_token = CancellationToken::new(); - let cancellation_token = self.cancellation_token.clone(); - let event_tx = self.event_tx.clone(); - - self.task = tokio::spawn(async move { - let mut reader = crossterm::event::EventStream::new(); - loop { - let crossterm_event = reader.next().fuse(); - tokio::select! { - _ = cancellation_token.cancelled() => break, - event = crossterm_event => Self::handle_crossterm_event(event, &event_tx)?, - } - } - Ok(()) - }); - Ok(()) - } - - pub(crate) fn exit(&mut self) -> Result<()> { - self.cancellation_token.cancel(); - let mut counter = 0; - while !self.task.is_finished() { - std::thread::sleep(Duration::from_millis(1)); - counter += 1; - if counter > 50 { - self.task.abort(); - } - if counter > 100 { - break; - } - } - if crossterm::terminal::is_raw_mode_enabled()? { - self.terminal.flush()?; - crossterm::execute!(std::io::stdout(), LeaveAlternateScreen, cursor::Show)?; - crossterm::terminal::disable_raw_mode()?; - } - Ok(()) - } - - pub async fn next(&mut self) -> Option { - self.event_rx.recv().await - } -} +mod components; +mod global_popups; +pub mod main_window; +mod tabs; +pub mod terminal; diff --git a/rm-main/src/tui/ui/tabs/mod.rs b/rm-main/src/tui/tabs/mod.rs similarity index 100% rename from rm-main/src/tui/ui/tabs/mod.rs rename to rm-main/src/tui/tabs/mod.rs diff --git a/rm-main/src/tui/ui/tabs/search/bottom_bar.rs b/rm-main/src/tui/tabs/search/bottom_bar.rs similarity index 98% rename from rm-main/src/tui/ui/tabs/search/bottom_bar.rs rename to rm-main/src/tui/tabs/search/bottom_bar.rs index 3c47b2d..f93ca82 100644 --- a/rm-main/src/tui/ui/tabs/search/bottom_bar.rs +++ b/rm-main/src/tui/tabs/search/bottom_bar.rs @@ -9,7 +9,7 @@ use rm_config::CONFIG; use rm_shared::action::{Action, UpdateAction}; use throbber_widgets_tui::ThrobberState; -use crate::tui::{app, ui::components::Component}; +use crate::tui::{app, components::Component}; use super::{ConfiguredProvider, ProviderState}; diff --git a/rm-main/src/tui/ui/tabs/search/mod.rs b/rm-main/src/tui/tabs/search/mod.rs similarity index 99% rename from rm-main/src/tui/ui/tabs/search/mod.rs rename to rm-main/src/tui/tabs/search/mod.rs index d90cbe7..8f03f59 100644 --- a/rm-main/src/tui/ui/tabs/search/mod.rs +++ b/rm-main/src/tui/tabs/search/mod.rs @@ -22,7 +22,7 @@ use crate::{ transmission::TorrentAction, tui::{ app, - ui::components::{table::GenericTable, Component, ComponentAction}, + components::{table::GenericTable, Component, ComponentAction}, }, }; use rm_shared::{ diff --git a/rm-main/src/tui/ui/tabs/search/popups/mod.rs b/rm-main/src/tui/tabs/search/popups/mod.rs similarity index 94% rename from rm-main/src/tui/ui/tabs/search/popups/mod.rs rename to rm-main/src/tui/tabs/search/popups/mod.rs index c11fe8f..c49f544 100644 --- a/rm-main/src/tui/ui/tabs/search/popups/mod.rs +++ b/rm-main/src/tui/tabs/search/popups/mod.rs @@ -6,8 +6,8 @@ use ratatui::Frame; use rm_shared::action::Action; use crate::tui::app; -use crate::tui::ui::components::Component; -use crate::tui::ui::components::ComponentAction; +use crate::tui::components::Component; +use crate::tui::components::ComponentAction; use super::ConfiguredProvider; diff --git a/rm-main/src/tui/ui/tabs/search/popups/providers.rs b/rm-main/src/tui/tabs/search/popups/providers.rs similarity index 98% rename from rm-main/src/tui/ui/tabs/search/popups/providers.rs rename to rm-main/src/tui/tabs/search/popups/providers.rs index 9df1855..781c454 100644 --- a/rm-main/src/tui/ui/tabs/search/popups/providers.rs +++ b/rm-main/src/tui/tabs/search/popups/providers.rs @@ -13,9 +13,9 @@ use ratatui::{ use rm_config::CONFIG; use rm_shared::action::Action; -use crate::tui::ui::{ - centered_rect, +use crate::tui::{ components::{Component, ComponentAction}, + main_window::centered_rect, tabs::search::{ConfiguredProvider, ProviderState}, }; diff --git a/rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs b/rm-main/src/tui/tabs/torrents/bottom_stats.rs similarity index 98% rename from rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs rename to rm-main/src/tui/tabs/torrents/bottom_stats.rs index 6a4fe01..2d9fb76 100644 --- a/rm-main/src/tui/ui/tabs/torrents/bottom_stats.rs +++ b/rm-main/src/tui/tabs/torrents/bottom_stats.rs @@ -8,7 +8,7 @@ use ratatui::{ use rm_shared::utils::bytes_to_human_format; use transmission_rpc::types::{FreeSpace, SessionStats}; -use crate::tui::ui::components::Component; +use crate::tui::components::Component; use super::table_manager::TableManager; diff --git a/rm-main/src/tui/ui/tabs/torrents/input_manager.rs b/rm-main/src/tui/tabs/torrents/input_manager.rs similarity index 97% rename from rm-main/src/tui/ui/tabs/torrents/input_manager.rs rename to rm-main/src/tui/tabs/torrents/input_manager.rs index 1865ec5..0f1706f 100644 --- a/rm-main/src/tui/ui/tabs/torrents/input_manager.rs +++ b/rm-main/src/tui/tabs/torrents/input_manager.rs @@ -6,7 +6,7 @@ use ratatui::{ use rm_config::CONFIG; use tui_input::{backend::crossterm::to_input_request, Input, InputResponse}; -use crate::tui::ui::components::Component; +use crate::tui::components::Component; pub struct InputManager { input: Input, diff --git a/rm-main/src/tui/ui/tabs/torrents/mod.rs b/rm-main/src/tui/tabs/torrents/mod.rs similarity index 99% rename from rm-main/src/tui/ui/tabs/torrents/mod.rs rename to rm-main/src/tui/tabs/torrents/mod.rs index 7e2c699..56a0624 100644 --- a/rm-main/src/tui/ui/tabs/torrents/mod.rs +++ b/rm-main/src/tui/tabs/torrents/mod.rs @@ -8,7 +8,7 @@ pub mod tasks; use crate::transmission::TorrentAction; use crate::tui::app; -use crate::tui::ui::components::{Component, ComponentAction}; +use crate::tui::components::{Component, ComponentAction}; use popups::stats::StatisticsPopup; use ratatui::prelude::*; diff --git a/rm-main/src/tui/ui/tabs/torrents/popups/files.rs b/rm-main/src/tui/tabs/torrents/popups/files.rs similarity index 99% rename from rm-main/src/tui/ui/tabs/torrents/popups/files.rs rename to rm-main/src/tui/tabs/torrents/popups/files.rs index cc29998..7c801c2 100644 --- a/rm-main/src/tui/ui/tabs/torrents/popups/files.rs +++ b/rm-main/src/tui/tabs/torrents/popups/files.rs @@ -17,10 +17,8 @@ use crate::{ transmission::TorrentAction, tui::{ app, - ui::{ - centered_rect, - components::{Component, ComponentAction}, - }, + components::{Component, ComponentAction}, + main_window::centered_rect, }, }; use rm_shared::{ diff --git a/rm-main/src/tui/ui/tabs/torrents/popups/mod.rs b/rm-main/src/tui/tabs/torrents/popups/mod.rs similarity index 97% rename from rm-main/src/tui/ui/tabs/torrents/popups/mod.rs rename to rm-main/src/tui/tabs/torrents/popups/mod.rs index ee68e87..e3874d2 100644 --- a/rm-main/src/tui/ui/tabs/torrents/popups/mod.rs +++ b/rm-main/src/tui/tabs/torrents/popups/mod.rs @@ -1,6 +1,6 @@ use crate::tui::{ app, - ui::components::{Component, ComponentAction}, + components::{Component, ComponentAction}, }; use self::{files::FilesPopup, stats::StatisticsPopup}; diff --git a/rm-main/src/tui/ui/tabs/torrents/popups/stats.rs b/rm-main/src/tui/tabs/torrents/popups/stats.rs similarity index 97% rename from rm-main/src/tui/ui/tabs/torrents/popups/stats.rs rename to rm-main/src/tui/tabs/torrents/popups/stats.rs index 2df6052..9f03a47 100644 --- a/rm-main/src/tui/ui/tabs/torrents/popups/stats.rs +++ b/rm-main/src/tui/tabs/torrents/popups/stats.rs @@ -13,9 +13,9 @@ use transmission_rpc::types::SessionStats; use rm_shared::{action::Action, utils::bytes_to_human_format}; -use crate::tui::ui::{ - centered_rect, +use crate::tui::{ components::{Component, ComponentAction}, + main_window::centered_rect, }; pub struct StatisticsPopup { diff --git a/rm-main/src/tui/ui/tabs/torrents/rustmission_torrent.rs b/rm-main/src/tui/tabs/torrents/rustmission_torrent.rs similarity index 100% rename from rm-main/src/tui/ui/tabs/torrents/rustmission_torrent.rs rename to rm-main/src/tui/tabs/torrents/rustmission_torrent.rs diff --git a/rm-main/src/tui/ui/tabs/torrents/table_manager.rs b/rm-main/src/tui/tabs/torrents/table_manager.rs similarity index 99% rename from rm-main/src/tui/ui/tabs/torrents/table_manager.rs rename to rm-main/src/tui/tabs/torrents/table_manager.rs index f868cee..69017a9 100644 --- a/rm-main/src/tui/ui/tabs/torrents/table_manager.rs +++ b/rm-main/src/tui/tabs/torrents/table_manager.rs @@ -4,7 +4,7 @@ use rm_config::CONFIG; use rm_shared::header::Header; use std::collections::HashMap; -use crate::tui::ui::components::table::GenericTable; +use crate::tui::components::table::GenericTable; use super::rustmission_torrent::RustmissionTorrent; diff --git a/rm-main/src/tui/ui/tabs/torrents/task_manager.rs b/rm-main/src/tui/tabs/torrents/task_manager.rs similarity index 99% rename from rm-main/src/tui/ui/tabs/torrents/task_manager.rs rename to rm-main/src/tui/tabs/torrents/task_manager.rs index 6a64515..bc6a7e4 100644 --- a/rm-main/src/tui/ui/tabs/torrents/task_manager.rs +++ b/rm-main/src/tui/tabs/torrents/task_manager.rs @@ -9,7 +9,7 @@ use rm_shared::{ use crate::tui::{ app, - ui::components::{Component, ComponentAction}, + components::{Component, ComponentAction}, }; use super::{ diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs b/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs similarity index 95% rename from rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs rename to rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs index 906bd6b..54bf916 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/add_magnet.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs @@ -5,10 +5,8 @@ use crate::{ transmission::TorrentAction, tui::{ app, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, - }, + components::{Component, ComponentAction}, + tabs::torrents::input_manager::InputManager, }, }; use rm_shared::{ diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/default.rs b/rm-main/src/tui/tabs/torrents/tasks/default.rs similarity index 92% rename from rm-main/src/tui/ui/tabs/torrents/tasks/default.rs rename to rm-main/src/tui/tabs/torrents/tasks/default.rs index 2209fc5..40126e1 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/default.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/default.rs @@ -1,7 +1,7 @@ use ratatui::prelude::*; use rm_config::CONFIG; -use crate::tui::ui::components::Component; +use crate::tui::components::Component; pub struct DefaultBar {} diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs b/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs similarity index 95% rename from rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs rename to rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs index 4b5204c..d97cf28 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/delete_torrent.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs @@ -4,8 +4,8 @@ use transmission_rpc::types::Id; use crate::transmission::TorrentAction; use crate::tui::app; -use crate::tui::ui::components::{Component, ComponentAction}; -use crate::tui::ui::tabs::torrents::input_manager::InputManager; +use crate::tui::components::{Component, ComponentAction}; +use crate::tui::tabs::torrents::input_manager::InputManager; use rm_shared::action::{Action, UpdateAction}; use rm_shared::status_task::StatusTask; diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs b/rm-main/src/tui/tabs/torrents/tasks/filter.rs similarity index 91% rename from rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs rename to rm-main/src/tui/tabs/torrents/tasks/filter.rs index 1b42129..bc4c727 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/filter.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/filter.rs @@ -5,10 +5,8 @@ use rm_shared::action::{Action, UpdateAction}; use crate::tui::{ app, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::{input_manager::InputManager, table_manager::Filter}, - }, + components::{Component, ComponentAction}, + tabs::torrents::{input_manager::InputManager, table_manager::Filter}, }; pub struct FilterBar { diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/mod.rs b/rm-main/src/tui/tabs/torrents/tasks/mod.rs similarity index 100% rename from rm-main/src/tui/ui/tabs/torrents/tasks/mod.rs rename to rm-main/src/tui/tabs/torrents/tasks/mod.rs diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs b/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs similarity index 93% rename from rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs rename to rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs index d84537a..c456ac9 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/move_torrent.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs @@ -10,10 +10,8 @@ use crate::{ transmission::TorrentAction, tui::{ app, - ui::{ - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, - }, + components::{Component, ComponentAction}, + tabs::torrents::input_manager::InputManager, }, }; diff --git a/rm-main/src/tui/ui/tabs/torrents/tasks/status.rs b/rm-main/src/tui/tabs/torrents/tasks/status.rs similarity index 98% rename from rm-main/src/tui/ui/tabs/torrents/tasks/status.rs rename to rm-main/src/tui/tabs/torrents/tasks/status.rs index bdf3849..1a124eb 100644 --- a/rm-main/src/tui/ui/tabs/torrents/tasks/status.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/status.rs @@ -6,7 +6,7 @@ use rm_shared::{ use throbber_widgets_tui::ThrobberState; use tokio::time::{self, Instant}; -use crate::tui::{app, ui::components::Component}; +use crate::tui::{app, components::Component}; pub struct StatusBar { task: StatusTask, diff --git a/rm-main/src/tui/terminal.rs b/rm-main/src/tui/terminal.rs new file mode 100644 index 0000000..35c31f7 --- /dev/null +++ b/rm-main/src/tui/terminal.rs @@ -0,0 +1,107 @@ +use std::{io, time::Duration}; + +use anyhow::Result; +use crossterm::{ + cursor, + event::{Event, KeyEventKind}, + terminal::{EnterAlternateScreen, LeaveAlternateScreen}, +}; +use futures::{FutureExt, StreamExt}; +use ratatui::{backend::CrosstermBackend as Backend, Terminal}; +use tokio::{ + sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, + task::JoinHandle, +}; +use tokio_util::sync::CancellationToken; + +pub struct Tui { + pub terminal: Terminal>, + pub task: JoinHandle>, + pub cancellation_token: CancellationToken, + pub event_rx: UnboundedReceiver, + pub event_tx: UnboundedSender, +} + +impl Tui { + pub(crate) fn new() -> Result { + let terminal = Terminal::new(Backend::new(std::io::stdout()))?; + let (event_tx, event_rx) = mpsc::unbounded_channel(); + let cancellation_token = CancellationToken::new(); + let task = tokio::spawn(async { Ok(()) }); + Ok(Self { + terminal, + task, + cancellation_token, + event_rx, + event_tx, + }) + } + + fn handle_crossterm_event( + event: Option>, + event_tx: &UnboundedSender, + ) -> Result<()> { + match event { + Some(Ok(Event::Key(key))) => { + if key.kind == KeyEventKind::Press { + event_tx.send(Event::Key(key)).unwrap(); + } + } + Some(Ok(Event::Resize(x, y))) => event_tx.send(Event::Resize(x, y)).unwrap(), + Some(Err(e)) => Err(e)?, + _ => (), + } + Ok(()) + } + + pub(crate) fn enter(&mut self) -> Result<()> { + crossterm::terminal::enable_raw_mode()?; + crossterm::execute!(std::io::stdout(), EnterAlternateScreen, cursor::Hide)?; + self.start()?; + Ok(()) + } + + pub fn start(&mut self) -> Result<()> { + self.cancellation_token = CancellationToken::new(); + let cancellation_token = self.cancellation_token.clone(); + let event_tx = self.event_tx.clone(); + + self.task = tokio::spawn(async move { + let mut reader = crossterm::event::EventStream::new(); + loop { + let crossterm_event = reader.next().fuse(); + tokio::select! { + _ = cancellation_token.cancelled() => break, + event = crossterm_event => Self::handle_crossterm_event(event, &event_tx)?, + } + } + Ok(()) + }); + Ok(()) + } + + pub(crate) fn exit(&mut self) -> Result<()> { + self.cancellation_token.cancel(); + let mut counter = 0; + while !self.task.is_finished() { + std::thread::sleep(Duration::from_millis(1)); + counter += 1; + if counter > 50 { + self.task.abort(); + } + if counter > 100 { + break; + } + } + if crossterm::terminal::is_raw_mode_enabled()? { + self.terminal.flush()?; + crossterm::execute!(std::io::stdout(), LeaveAlternateScreen, cursor::Show)?; + crossterm::terminal::disable_raw_mode()?; + } + Ok(()) + } + + pub async fn next(&mut self) -> Option { + self.event_rx.recv().await + } +} From 041f7b03ee9ec92678def7d78ca0b4fcc8800502 Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Tue, 13 Aug 2024 18:10:37 +0200 Subject: [PATCH 6/6] move input_manager to components --- rm-main/src/tui/app.rs | 2 +- .../tui/{tabs/torrents => components}/input_manager.rs | 0 rm-main/src/tui/components/mod.rs | 9 +++++++-- rm-main/src/tui/main_window.rs | 4 ++-- rm-main/src/tui/tabs/search/mod.rs | 2 +- rm-main/src/tui/tabs/torrents/mod.rs | 1 - rm-main/src/tui/tabs/torrents/table_manager.rs | 2 +- rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs | 5 ++--- rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs | 5 ++--- rm-main/src/tui/tabs/torrents/tasks/filter.rs | 4 ++-- rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs | 3 +-- 11 files changed, 19 insertions(+), 18 deletions(-) rename rm-main/src/tui/{tabs/torrents => components}/input_manager.rs (100%) diff --git a/rm-main/src/tui/app.rs b/rm-main/src/tui/app.rs index 4e987af..4d4b31a 100644 --- a/rm-main/src/tui/app.rs +++ b/rm-main/src/tui/app.rs @@ -13,7 +13,7 @@ use crossterm::event::{Event, KeyCode, KeyModifiers}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use transmission_rpc::{types::SessionGet, TransClient}; -use super::{components::tabs::CurrentTab, main_window::MainWindow, terminal::Tui}; +use super::{components::CurrentTab, main_window::MainWindow, terminal::Tui}; #[derive(Clone)] pub struct Ctx { diff --git a/rm-main/src/tui/tabs/torrents/input_manager.rs b/rm-main/src/tui/components/input_manager.rs similarity index 100% rename from rm-main/src/tui/tabs/torrents/input_manager.rs rename to rm-main/src/tui/components/input_manager.rs diff --git a/rm-main/src/tui/components/mod.rs b/rm-main/src/tui/components/mod.rs index a8fdd47..2e15a81 100644 --- a/rm-main/src/tui/components/mod.rs +++ b/rm-main/src/tui/components/mod.rs @@ -1,5 +1,10 @@ -pub mod table; -pub mod tabs; +mod input_manager; +mod table; +mod tabs; + +pub use input_manager::InputManager; +pub use table::GenericTable; +pub use tabs::{CurrentTab, TabComponent}; use ratatui::prelude::*; use ratatui::Frame; diff --git a/rm-main/src/tui/main_window.rs b/rm-main/src/tui/main_window.rs index 1ed5a07..d3cbbf6 100644 --- a/rm-main/src/tui/main_window.rs +++ b/rm-main/src/tui/main_window.rs @@ -2,11 +2,11 @@ use ratatui::prelude::*; use rm_shared::action::{Action, UpdateAction}; -use crate::tui::components::tabs::CurrentTab; +use crate::tui::components::CurrentTab; use super::{ app, - components::{tabs::TabComponent, Component, ComponentAction}, + components::{Component, ComponentAction, TabComponent}, global_popups::{ErrorPopup, GlobalPopupManager}, tabs::{search::SearchTab, torrents::TorrentsTab}, }; diff --git a/rm-main/src/tui/tabs/search/mod.rs b/rm-main/src/tui/tabs/search/mod.rs index 8f03f59..a94447b 100644 --- a/rm-main/src/tui/tabs/search/mod.rs +++ b/rm-main/src/tui/tabs/search/mod.rs @@ -22,7 +22,7 @@ use crate::{ transmission::TorrentAction, tui::{ app, - components::{table::GenericTable, Component, ComponentAction}, + components::{Component, ComponentAction, GenericTable}, }, }; use rm_shared::{ diff --git a/rm-main/src/tui/tabs/torrents/mod.rs b/rm-main/src/tui/tabs/torrents/mod.rs index 56a0624..d64e606 100644 --- a/rm-main/src/tui/tabs/torrents/mod.rs +++ b/rm-main/src/tui/tabs/torrents/mod.rs @@ -1,5 +1,4 @@ mod bottom_stats; -mod input_manager; pub mod popups; pub mod rustmission_torrent; pub mod table_manager; diff --git a/rm-main/src/tui/tabs/torrents/table_manager.rs b/rm-main/src/tui/tabs/torrents/table_manager.rs index 69017a9..74e5b13 100644 --- a/rm-main/src/tui/tabs/torrents/table_manager.rs +++ b/rm-main/src/tui/tabs/torrents/table_manager.rs @@ -4,7 +4,7 @@ use rm_config::CONFIG; use rm_shared::header::Header; use std::collections::HashMap; -use crate::tui::components::table::GenericTable; +use crate::tui::components::GenericTable; use super::rustmission_torrent::RustmissionTorrent; diff --git a/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs b/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs index 54bf916..60da468 100644 --- a/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/add_magnet.rs @@ -5,8 +5,7 @@ use crate::{ transmission::TorrentAction, tui::{ app, - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, + components::{Component, ComponentAction, InputManager}, }, }; use rm_shared::{ @@ -57,7 +56,7 @@ impl AddMagnetBar { return ComponentAction::Quit; } - if let Some(_) = self.input_magnet_mgr.handle_key(input) { + if self.input_magnet_mgr.handle_key(input).is_some() { self.ctx.send_action(Action::Render); } diff --git a/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs b/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs index d97cf28..295f577 100644 --- a/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/delete_torrent.rs @@ -4,8 +4,7 @@ use transmission_rpc::types::Id; use crate::transmission::TorrentAction; use crate::tui::app; -use crate::tui::components::{Component, ComponentAction}; -use crate::tui::tabs::torrents::input_manager::InputManager; +use crate::tui::components::{Component, ComponentAction, InputManager}; use rm_shared::action::{Action, UpdateAction}; use rm_shared::status_task::StatusTask; @@ -80,7 +79,7 @@ impl Component for DeleteBar { } } - if let Some(_) = self.input_mgr.handle_key(input) { + if self.input_mgr.handle_key(input).is_some() { self.ctx.send_action(Action::Render); } diff --git a/rm-main/src/tui/tabs/torrents/tasks/filter.rs b/rm-main/src/tui/tabs/torrents/tasks/filter.rs index bc4c727..d0a0bb8 100644 --- a/rm-main/src/tui/tabs/torrents/tasks/filter.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/filter.rs @@ -5,8 +5,8 @@ use rm_shared::action::{Action, UpdateAction}; use crate::tui::{ app, - components::{Component, ComponentAction}, - tabs::torrents::{input_manager::InputManager, table_manager::Filter}, + components::{Component, ComponentAction, InputManager}, + tabs::torrents::table_manager::Filter, }; pub struct FilterBar { diff --git a/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs b/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs index c456ac9..0495afe 100644 --- a/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs +++ b/rm-main/src/tui/tabs/torrents/tasks/move_torrent.rs @@ -10,8 +10,7 @@ use crate::{ transmission::TorrentAction, tui::{ app, - components::{Component, ComponentAction}, - tabs::torrents::input_manager::InputManager, + components::{Component, ComponentAction, InputManager}, }, };