Skip to content

Commit

Permalink
Implement list and text entry actions (basic)
Browse files Browse the repository at this point in the history
  • Loading branch information
nick42d committed Dec 3, 2024
1 parent 8af6319 commit 9d3225f
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 30 deletions.
3 changes: 0 additions & 3 deletions youtui/src/app/component/actionhandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,6 @@ pub fn count_visible_keybinds<K: KeyRouter<A>, A: Action + 'static>(component: &
.filter(|(_, kt)| (*kt).get_visibility() != CommandVisibility::Hidden)
.count()
}
pub trait ContainsList {
fn list_is_active(&self) -> bool;
}
/// A component of the application that handles text entry, currently designed
/// to wrap rat_text::TextInputState.
pub trait TextHandler: Component {
Expand Down
76 changes: 54 additions & 22 deletions youtui/src/app/ui.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use self::{browser::Browser, logger::Logger, playlist::Playlist};
use super::component::actionhandler::{
count_visible_keybinds, handle_key_stack, Action, ComponentEffect, ContainsList,
DominantKeyRouter, KeyHandleAction, KeyRouter, Keymap, TextHandler,
count_visible_keybinds, handle_key_stack, Action, ComponentEffect, DominantKeyRouter,
KeyHandleAction, KeyRouter, Keymap, TextHandler,
};
use super::keycommand::{DisplayableCommand, DisplayableMode};
use super::server::{ArcServer, IncreaseVolume, TaskMetadata};
Expand Down Expand Up @@ -83,24 +83,11 @@ impl Scrollable for HelpMenu {
.saturating_add_signed(amount)
.min(self.len.saturating_sub(1));
}

fn get_selected_item(&self) -> usize {
self.cur
}
}

impl ContainsList for YoutuiWindow {
// TODO: propogate implementation down.
fn list_is_active(&self) -> bool {
self.help.shown
|| match self.context {
WindowContext::Browser => {
!self.browser.artist_list.search_popped
|| self.browser.input_routing == browser::InputRouting::Song
}
WindowContext::Playlist => true,
WindowContext::Logs => false,
}
fn is_scrollable(&self) -> bool {
todo!()
}
}

Expand Down Expand Up @@ -130,11 +117,31 @@ impl DominantKeyRouter<AppAction> for YoutuiWindow {
}
}

impl Scrollable for YoutuiWindow {
fn increment_list(&mut self, amount: isize) {
todo!()
}
fn get_selected_item(&self) -> usize {
todo!()
}
fn is_scrollable(&self) -> bool {
self.help.shown
|| match self.context {
WindowContext::Browser => {
!self.browser.artist_list.search_popped
|| self.browser.input_routing == browser::InputRouting::Song
}
WindowContext::Playlist => true,
WindowContext::Logs => false,
}
}
}

impl KeyRouter<AppAction> for YoutuiWindow {
fn get_active_keybinds(&self) -> impl Iterator<Item = &Keymap<AppAction>> {
// If Browser has dominant keybinds, self keybinds shouldn't be visible.
let kb = std::iter::once(&self.keybinds);
let kb = if self.list_is_active() {
let kb = if self.is_scrollable() {
Either::Left(kb.chain(std::iter::once(&self.list_keybinds)))
} else {
Either::Right(kb)
Expand Down Expand Up @@ -164,6 +171,9 @@ impl KeyRouter<AppAction> for YoutuiWindow {

impl TextHandler for YoutuiWindow {
fn is_text_handling(&self) -> bool {
if self.help.shown {
return false;
}
match self.context {
WindowContext::Browser => self.browser.is_text_handling(),
WindowContext::Playlist => self.playlist.is_text_handling(),
Expand Down Expand Up @@ -263,15 +273,37 @@ impl YoutuiWindow {
}
pub fn handle_list_action(&mut self, action: ListAction) -> ComponentEffect<Self> {
if self.help.shown {
todo!();
match action {
ListAction::Up => self.help.increment_list(-1),
ListAction::Down => self.help.increment_list(1),
}
return AsyncTask::new_no_op();
}
match self.context {
WindowContext::Browser => todo!(),
WindowContext::Playlist => todo!(),
WindowContext::Browser => self
.browser
.handle_list_action(action)
.map(|this: &mut Self| &mut this.browser),
WindowContext::Playlist => self
.playlist
.handle_list_action(action)
.map(|this: &mut Self| &mut this.playlist),
WindowContext::Logs => AsyncTask::new_no_op(),
}
}
pub fn handle_text_entry_action(&mut self, action: TextEntryAction) -> ComponentEffect<Self> {
if !self.is_text_handling() {
return AsyncTask::new_no_op();
}
match self.context {
WindowContext::Browser => self
.browser
.handle_text_entry_action(action)
.map(|this: &mut Self| &mut this.browser),
WindowContext::Playlist => AsyncTask::new_no_op(),
WindowContext::Logs => AsyncTask::new_no_op(),
}
}
pub fn handle_text_entry_action(&mut self, action: TextEntryAction) -> ComponentEffect<Self> {}
pub fn pauseplay(&mut self) -> ComponentEffect<Self> {
self.playlist
.pauseplay()
Expand Down
2 changes: 1 addition & 1 deletion youtui/src/app/ui/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl Action for HelpAction {
}
fn describe(&self) -> std::borrow::Cow<str> {
match self {
HelpAction::Close => "Close Help".return state.handle_text_entry_action(a)into(),
HelpAction::Close => "Close Help".into(),
}
}
async fn apply(
Expand Down
35 changes: 34 additions & 1 deletion youtui/src/app/ui/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use self::{
artistalbums::{albumsongs::AlbumSongsPanel, artistsearch::ArtistSearchPanel},
draw::draw_browser,
};
use super::{action::AppAction, AppCallback, WindowContext};
use super::{
action::{AppAction, ListAction, TextEntryAction},
AppCallback, WindowContext,
};
use crate::app::{
component::actionhandler::{
Action, Component, ComponentEffect, DominantKeyRouter, KeyRouter, Suggestable, TextHandler,
Expand Down Expand Up @@ -227,6 +230,36 @@ impl Browser {
// Doesn't consider previous routing.
self.input_routing = self.input_routing.right();
}
pub fn handle_list_action(&mut self, action: ListAction) -> ComponentEffect<Self> {
match self.input_routing {
InputRouting::Artist => self
.artist_list
.handle_list_action(action)
.map(|this: &mut Self| &mut this.artist_list),
InputRouting::Song => self
.album_songs_list
.handle_list_action(action)
.map(|this: &mut Self| &mut this.album_songs_list),
}
}
pub fn handle_text_entry_action(&mut self, action: TextEntryAction) -> ComponentEffect<Self> {
if self.is_text_handling()
&& self.artist_list.search_popped
&& self.input_routing == InputRouting::Artist
{
match action {
TextEntryAction::Submit => return self.get_songs(),
// Handled by old handle_text_event_impl.
//
// TODO: remove the duplication of responsibilities between this function and
// handle_text_event_impl.
TextEntryAction::Left => (),
TextEntryAction::Right => (),
TextEntryAction::Backspace => (),
}
}
AsyncTask::new_no_op()
}
pub fn handle_toggle_search(&mut self) {
if self.artist_list.search_popped {
self.artist_list.close_search();
Expand Down
22 changes: 21 additions & 1 deletion youtui/src/app/ui/browser/artistalbums/albumsongs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::app::component::actionhandler::{
};
use crate::app::server::{ArcServer, TaskMetadata};
use crate::app::structures::{ListSong, SongListComponent};
use crate::app::ui::action::AppAction;
use crate::app::ui::action::{AppAction, ListAction};
use crate::app::ui::browser::Browser;
use crate::app::view::{
Filter, FilterString, SortDirection, SortableTableView, TableFilterCommand, TableSortCommand,
Expand Down Expand Up @@ -340,6 +340,23 @@ impl AlbumSongsPanel {
self.sort.shown = false;
self.route = AlbumSongsInputRouting::List;
}
pub fn handle_list_action(&mut self, action: ListAction) -> ComponentEffect<Self> {
if self.sort.shown {
match action {
ListAction::Up => self.handle_sort_up(),
ListAction::Down => self.handle_sort_down(),
}
return AsyncTask::new_no_op();
}
if self.filter.shown {
return AsyncTask::new_no_op();
}
match action {
ListAction::Up => self.increment_list(-1),
ListAction::Down => self.increment_list(1),
}
AsyncTask::new_no_op()
}
pub fn handle_pop_sort(&mut self) {
// If no sortable columns, should we not handle this command?
self.sort.cur = 0;
Expand Down Expand Up @@ -471,6 +488,9 @@ impl Scrollable for AlbumSongsPanel {
fn get_selected_item(&self) -> usize {
self.cur_selected
}
fn is_scrollable(&self) -> bool {
todo!()
}
}

impl TableView for AlbumSongsPanel {
Expand Down
18 changes: 17 additions & 1 deletion youtui/src/app/ui/browser/artistalbums/artistsearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use crate::{
Action, Component, ComponentEffect, KeyRouter, Keymap, Suggestable, TextHandler,
},
server::{ArcServer, GetSearchSuggestions, TaskMetadata},
ui::{action::AppAction, browser::Browser},
ui::{
action::{AppAction, ListAction},
browser::Browser,
},
view::{ListView, Loadable, Scrollable, SortableList},
},
config::Config,
Expand Down Expand Up @@ -135,6 +138,16 @@ impl ArtistSearchPanel {
self.search_popped = false;
self.route = ArtistInputRouting::List;
}
pub fn handle_list_action(&mut self, action: ListAction) -> ComponentEffect<Self> {
if self.route != ArtistInputRouting::List {
return AsyncTask::new_no_op();
}
match action {
ListAction::Up => self.increment_list(-1),
ListAction::Down => self.increment_list(1),
}
AsyncTask::new_no_op()
}
}
impl Component for ArtistSearchPanel {
type Bkend = ArcServer;
Expand Down Expand Up @@ -283,6 +296,9 @@ impl Scrollable for ArtistSearchPanel {
fn get_selected_item(&self) -> usize {
self.selected
}
fn is_scrollable(&self) -> bool {
todo!()
}
}

impl SortableList for ArtistSearchPanel {
Expand Down
12 changes: 11 additions & 1 deletion youtui/src/app/ui/playlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use std::{borrow::Cow, fmt::Debug};
use tokio::sync::mpsc;
use tracing::{error, info, warn};

use super::action::AppAction;
use super::action::{AppAction, ListAction};

const SONGS_AHEAD_TO_BUFFER: usize = 3;
const SONGS_BEHIND_TO_SAVE: usize = 1;
Expand Down Expand Up @@ -150,6 +150,9 @@ impl Scrollable for Playlist {
fn get_selected_item(&self) -> usize {
self.cur_selected
}
fn is_scrollable(&self) -> bool {
true
}
}

impl TableView for Playlist {
Expand Down Expand Up @@ -601,6 +604,13 @@ impl Playlist {
// XXX: Consider downloading upcoming songs here.
// self.download_upcoming_songs().await;
}
pub fn handle_list_action(&mut self, action: ListAction) -> ComponentEffect<Self> {
match action {
ListAction::Up => self.increment_list(-1),
ListAction::Down => self.increment_list(1),
}
AsyncTask::new_no_op()
}
/// Handle seek command (from global keypress).
pub fn handle_seek(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions youtui/src/app/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ pub trait Scrollable {
// Increment the list by the specified amount.
fn increment_list(&mut self, amount: isize);
fn get_selected_item(&self) -> usize;
fn is_scrollable(&self) -> bool;
}
/// A struct that can either be scrolled or forward scroll commands to a
/// component.
Expand Down

0 comments on commit 9d3225f

Please sign in to comment.