Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove utils::{new_list_state,new_table_state} #532

Merged
merged 2 commits into from
Aug 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions spotify_player/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use crate::{
key::{Key, KeySequence},
state::*,
ui::single_line_input::LineInput,
utils::{new_list_state, parse_uri},
utils::parse_uri,
};

#[cfg(feature = "lyric-finder")]
use crate::utils::map_join;
use anyhow::{Context as _, Result};

use clipboard::{execute_copy_command, get_clipboard_content};
use tui::widgets::ListState;

mod clipboard;
mod page;
Expand Down Expand Up @@ -159,7 +160,7 @@ pub fn handle_action_in_context(
client_pub.send(ClientRequest::GetUserPlaylists)?;
ui.popup = Some(PopupState::UserPlaylistList(
PlaylistPopupAction::AddTrack(track.id),
new_list_state(),
ListState::default(),
));
}
Action::ToggleLiked => {
Expand Down Expand Up @@ -196,7 +197,7 @@ pub fn handle_action_in_context(
album,
context.get_available_actions(data),
)),
new_list_state(),
ListState::default(),
));
}
}
Expand Down Expand Up @@ -320,7 +321,7 @@ fn handle_go_to_artist(artists: Vec<Artist>, ui: &mut UIStateGuard) {
ui.popup = Some(PopupState::ArtistList(
ArtistPopupAction::Browse,
artists,
new_list_state(),
ListState::default(),
));
}
}
Expand All @@ -334,13 +335,13 @@ fn handle_show_actions_on_artist(
let actions = construct_artist_actions(&artists[0], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Artist(artists[0].clone(), actions)),
new_list_state(),
ListState::default(),
));
} else {
ui.popup = Some(PopupState::ArtistList(
ArtistPopupAction::ShowActions,
artists,
new_list_state(),
ListState::default(),
));
}
}
Expand Down Expand Up @@ -428,7 +429,7 @@ fn handle_global_command(
let actions = command::construct_track_actions(&track, &data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Track(track, actions)),
new_list_state(),
ListState::default(),
));
}
}
Expand All @@ -444,16 +445,16 @@ fn handle_global_command(
client_pub.send(ClientRequest::GetUserPlaylists)?;
ui.popup = Some(PopupState::UserPlaylistList(
PlaylistPopupAction::Browse,
new_list_state(),
ListState::default(),
));
}
Command::BrowseUserFollowedArtists => {
client_pub.send(ClientRequest::GetUserFollowedArtists)?;
ui.popup = Some(PopupState::UserFollowedArtistList(new_list_state()));
ui.popup = Some(PopupState::UserFollowedArtistList(ListState::default()));
}
Command::BrowseUserSavedAlbums => {
client_pub.send(ClientRequest::GetUserSavedAlbums)?;
ui.popup = Some(PopupState::UserSavedAlbumList(new_list_state()));
ui.popup = Some(PopupState::UserSavedAlbumList(ListState::default()));
}
Command::TopTrackPage => {
ui.new_page(PageState::Context {
Expand Down Expand Up @@ -500,7 +501,7 @@ fn handle_global_command(
Command::BrowsePage => {
ui.new_page(PageState::Browse {
state: BrowsePageUIState::CategoryList {
state: new_list_state(),
state: ListState::default(),
},
});
client_pub.send(ClientRequest::GetBrowseCategories)?;
Expand Down Expand Up @@ -576,7 +577,7 @@ fn handle_global_command(
}
}
Command::SwitchDevice => {
ui.popup = Some(PopupState::DeviceList(new_list_state()));
ui.popup = Some(PopupState::DeviceList(ListState::default()));
client_pub.send(ClientRequest::GetDevices)?;
}
Command::SwitchTheme => {
Expand All @@ -588,7 +589,7 @@ fn handle_global_command(
themes.insert(0, theme);
}

ui.popup = Some(PopupState::ThemeList(themes, new_list_state()));
ui.popup = Some(PopupState::ThemeList(themes, ListState::default()));
}
#[cfg(feature = "streaming")]
Command::RestartIntegratedClient => {
Expand Down
2 changes: 1 addition & 1 deletion spotify_player/src/event/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ fn handle_command_for_browse_page(
ui.new_page(PageState::Browse {
state: BrowsePageUIState::CategoryPlaylistList {
category: categories[selected].clone(),
state: new_list_state(),
state: ListState::default(),
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion spotify_player/src/event/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub fn handle_key_sequence_for_popup(
};
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Artist(artists[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
}
Expand Down
12 changes: 6 additions & 6 deletions spotify_player/src/event/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ fn handle_playlist_modify_command(
actions.push(Action::DeleteFromPlaylist);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
return Ok(true);
}
Expand Down Expand Up @@ -325,7 +325,7 @@ fn handle_command_for_track_table_window(
let actions = command::construct_track_actions(filtered_tracks[id], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
Command::AddSelectedItemToQueue => {
Expand Down Expand Up @@ -369,7 +369,7 @@ pub fn handle_command_for_track_list_window(
let actions = command::construct_track_actions(tracks[id], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
Command::AddSelectedItemToQueue => {
Expand Down Expand Up @@ -407,7 +407,7 @@ pub fn handle_command_for_artist_list_window(
let actions = construct_artist_actions(artists[id], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Artist(artists[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
_ => return Ok(false),
Expand Down Expand Up @@ -443,7 +443,7 @@ pub fn handle_command_for_album_list_window(
let actions = construct_album_actions(albums[id], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Album(albums[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
Command::AddSelectedItemToQueue => {
Expand Down Expand Up @@ -481,7 +481,7 @@ pub fn handle_command_for_playlist_list_window(
let actions = construct_playlist_actions(playlists[id], data);
ui.popup = Some(PopupState::ActionList(
Box::new(ActionListItem::Playlist(playlists[id].clone(), actions)),
new_list_state(),
ListState::default(),
));
}
_ => return Ok(false),
Expand Down
28 changes: 14 additions & 14 deletions spotify_player/src/state/ui/page.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{state::model::*, ui::single_line_input::LineInput, utils};
use crate::{state::model::*, ui::single_line_input::LineInput};
use tui::widgets::{ListState, TableState};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -229,9 +229,9 @@ impl PageState {
impl LibraryPageUIState {
pub fn new() -> Self {
Self {
playlist_list: utils::new_list_state(),
saved_album_list: utils::new_list_state(),
followed_artist_list: utils::new_list_state(),
playlist_list: ListState::default(),
saved_album_list: ListState::default(),
followed_artist_list: ListState::default(),
focus: LibraryFocusState::Playlists,
}
}
Expand All @@ -240,10 +240,10 @@ impl LibraryPageUIState {
impl SearchPageUIState {
pub fn new() -> Self {
Self {
track_list: utils::new_list_state(),
album_list: utils::new_list_state(),
artist_list: utils::new_list_state(),
playlist_list: utils::new_list_state(),
track_list: ListState::default(),
album_list: ListState::default(),
artist_list: ListState::default(),
playlist_list: ListState::default(),
focus: SearchFocusState::Input,
}
}
Expand All @@ -266,28 +266,28 @@ impl ContextPageType {
impl ContextPageUIState {
pub fn new_playlist() -> Self {
Self::Playlist {
track_table: utils::new_table_state(),
track_table: TableState::default(),
}
}

pub fn new_album() -> Self {
Self::Album {
track_table: utils::new_table_state(),
track_table: TableState::default(),
}
}

pub fn new_artist() -> Self {
Self::Artist {
top_track_table: utils::new_table_state(),
album_table: utils::new_table_state(),
related_artist_list: utils::new_list_state(),
top_track_table: TableState::default(),
album_table: TableState::default(),
related_artist_list: ListState::default(),
focus: ArtistFocusState::TopTracks,
}
}

pub fn new_tracks() -> Self {
Self::Tracks {
track_table: utils::new_table_state(),
track_table: TableState::default(),
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions spotify_player/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ fn clean_up(mut terminal: Terminal) -> Result<()> {

/// Render the application
fn render_application(frame: &mut Frame, state: &SharedState, ui: &mut UIStateGuard, rect: Rect) {
// rendering order: shortcut help popup -> playback window -> other popups -> main layout
// rendering order: playback window -> shortcut help popup -> other popups -> main layout

let rect = popup::render_shortcut_help_popup(frame, ui, rect);

// render playback window before other popups to ensure no popup is rendered on top
// of the playback window
// render playback window before other popups and windows to ensure nothing is rendered on top
// of the playback window, which is to avoid "duplicated images" issue
// See: https://github.com/aome510/spotify-player/issues/498
let rect = playback::render_playback_window(frame, state, ui, rect);

let rect = popup::render_shortcut_help_popup(frame, ui, rect);

let (rect, is_active) = popup::render_popup(frame, state, ui, rect);

render_main_layout(is_active, frame, state, ui, rect);
Expand Down
23 changes: 13 additions & 10 deletions spotify_player/src/ui/playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ pub fn render_playback_window(
};

if needs_clear {
// clear the image's area to ensure no remaining artifacts before rendering the image
// clear the image's both new and old areas to ensure no remaining artifacts before rendering the image
// See: https://github.com/aome510/spotify-player/issues/389
frame.render_widget(Clear, cover_img_rect);
clear_area(frame, ui.last_cover_image_render_info.render_area);
clear_area(frame, cover_img_rect);
} else {
if !ui.last_cover_image_render_info.rendered {
if let Err(err) = render_playback_cover_image(state, ui) {
Expand Down Expand Up @@ -118,14 +119,7 @@ pub fn render_playback_window(
#[cfg(feature = "image")]
{
if ui.last_cover_image_render_info.rendered {
let rect = ui.last_cover_image_render_info.render_area;
// reset the `skip` state of cells in the cover image area
// in order to render the "No playback found" message
for x in rect.left()..rect.right() {
for y in rect.top()..rect.bottom() {
frame.buffer_mut().get_mut(x, y).set_skip(false);
}
}
clear_area(frame, ui.last_cover_image_render_info.render_area);
ui.last_cover_image_render_info = Default::default();
}
}
Expand All @@ -144,6 +138,15 @@ pub fn render_playback_window(
other_rect
}

#[cfg(feature = "image")]
fn clear_area(frame: &mut Frame, rect: Rect) {
for x in rect.left()..rect.right() {
for y in rect.top()..rect.bottom() {
frame.buffer_mut().get_mut(x, y).reset();
}
}
}

fn construct_playback_text(
ui: &UIStateGuard,
track: &rspotify_model::FullTrack,
Expand Down
8 changes: 6 additions & 2 deletions spotify_player/src/ui/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ pub fn construct_list_widget<'a>(
)
}

// Adjust the `selected` position of a `ListState` if that position is out of index
/// adjust the `selected` position of a `ListState` if that position is invalid
fn adjust_list_state(state: &mut ListState, len: usize) {
if let Some(p) = state.selected() {
if p >= len {
state.select(if len > 0 { Some(len - 1) } else { Some(0) });
}
} else if len > 0 {
state.select(Some(0));
}
}

Expand All @@ -93,12 +95,14 @@ pub fn render_list_window(
frame.render_stateful_widget(widget, rect, state);
}

// Adjust the `selected` position of a `TableState` if that position is out of index
/// adjust the `selected` position of a `TableState` if that position is invalid
fn adjust_table_state(state: &mut TableState, len: usize) {
if let Some(p) = state.selected() {
if p >= len {
state.select(if len > 0 { Some(len - 1) } else { Some(0) });
}
} else if len > 0 {
state.select(Some(0));
}
}

Expand Down
14 changes: 0 additions & 14 deletions spotify_player/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
use std::borrow::Cow;

use tui::widgets::*;

/// formats a time duration into a "{minutes}:{seconds}" format
pub fn format_duration(duration: &chrono::Duration) -> String {
let secs = duration.num_seconds();
format!("{}:{:02}", secs / 60, secs % 60)
}

pub fn new_list_state() -> ListState {
let mut state = ListState::default();
state.select(Some(0));
state
}

pub fn new_table_state() -> TableState {
let mut state = TableState::default();
state.select(Some(0));
state
}

pub fn map_join<T, F>(v: &[T], f: F, sep: &str) -> String
where
F: Fn(&T) -> &str,
Expand Down
Loading