Skip to content

Commit

Permalink
Extend layout functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
NickTheWilder committed Oct 14, 2024
1 parent 8dcbc22 commit dbc6e92
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 72 deletions.
47 changes: 39 additions & 8 deletions spotify_player/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ pub struct LayoutConfig {

#[derive(Debug, Deserialize, Serialize, ConfigParse, Clone)]
pub struct LibraryLayoutConfig {
pub playlist_percent: u16,
pub album_percent: u16,
pub playlist_percent: Option<u16>,
pub album_percent: Option<u16>,
pub artist_percent: Option<u16>,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
Expand Down Expand Up @@ -339,8 +340,9 @@ impl Default for LayoutConfig {
fn default() -> Self {
Self {
library: LibraryLayoutConfig {
playlist_percent: 40,
album_percent: 40,
playlist_percent: Some(40),
album_percent: Some(40),
artist_percent: Some(20),
},
playback_window_position: Position::Top,
playback_window_height: 6,
Expand All @@ -350,8 +352,28 @@ impl Default for LayoutConfig {

impl LayoutConfig {
fn check_values(&self) -> anyhow::Result<()> {
if self.library.album_percent + self.library.playlist_percent > 99 {
anyhow::bail!("Invalid library layout: summation of album_percent and playlist_percent cannot be greater than 99!");
let mut total_percent = 0;
let mut set_columns = 0;

if let Some(percent) = self.library.playlist_percent {
total_percent += percent;
set_columns += 1;
}
if let Some(percent) = self.library.album_percent {
total_percent += percent;
set_columns += 1;
}
if let Some(percent) = self.library.artist_percent {
total_percent += percent;
set_columns += 1;
}

if total_percent > 100 {
anyhow::bail!(
"Invalid library layout: summation of set percentages cannot be greater than 100!"
);
} else if set_columns == 0 {
anyhow::bail!("Invalid library layout: at least one of album_percent, playlist_percent, or artist_percentage must be set!");
} else {
Ok(())
}
Expand All @@ -361,8 +383,17 @@ impl LayoutConfig {
impl AppConfig {
pub fn new(path: &Path) -> Result<Self> {
let mut config = Self::default();
if !config.parse_config_file(path)? {
config.write_config_file(path)?
if config.parse_config_file(path)? {
// If a config file was found and parsed, reset the library percentages
// to ensure only the user-specified values are set
config.layout.library.playlist_percent = None;
config.layout.library.album_percent = None;
config.layout.library.artist_percent = None;

// Re-parse the config file to set only the user-specified values
config.parse_config_file(path)?;
} else {
config.write_config_file(path)?;
}

config.layout.check_values()?;
Expand Down
168 changes: 104 additions & 64 deletions spotify_player/src/ui/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ pub fn render_library_page(
let data = state.data.read();
let configs = config::get_config();

let (focus_state, playlist_folder_id) = match ui.current_page() {
PageState::Library { state } => (state.focus, state.playlist_folder_id),
let focus_state = match ui.current_page() {
PageState::Library { state } => state.focus,
_ => return,
};

Expand All @@ -328,52 +328,84 @@ pub fn render_library_page(
// - a saved albums window
// - a followed artists window

let chunks = Layout::horizontal([
Constraint::Percentage(configs.app_config.layout.library.playlist_percent),
Constraint::Percentage(configs.app_config.layout.library.album_percent),
Constraint::Percentage(
100 - (configs.app_config.layout.library.album_percent
+ configs.app_config.layout.library.playlist_percent),
),
])
.split(rect);

let playlist_rect = construct_and_render_block(
"Playlists",
&ui.theme,
Borders::TOP | Borders::LEFT | Borders::BOTTOM,
frame,
chunks[0],
);
let album_rect = construct_and_render_block(
"Albums",
&ui.theme,
Borders::TOP | Borders::LEFT | Borders::BOTTOM,
frame,
chunks[1],
);
let artist_rect =
construct_and_render_block("Artists", &ui.theme, Borders::ALL, frame, chunks[2]);
// Calculate constraints based on visible columns
let mut constraints: Vec<Constraint> = Vec::new();
if let Some(percent) = configs.app_config.layout.library.playlist_percent {
constraints.push(Constraint::Percentage(percent));
}
if let Some(percent) = configs.app_config.layout.library.album_percent {
constraints.push(Constraint::Percentage(percent));
}
if let Some(percent) = configs.app_config.layout.library.artist_percent {
constraints.push(Constraint::Percentage(percent));
}

let total_sections = constraints.len();
let chunks = Layout::horizontal(&constraints).split(rect);

let mut _chunk_index = 0;

let mut playlist_rect = None;
let mut album_rect = None;
let mut artist_rect = None;

if configs.app_config.layout.library.playlist_percent.is_some() {
let borders = if _chunk_index == total_sections - 1 {
Borders::ALL
} else {
Borders::TOP | Borders::LEFT | Borders::BOTTOM
};
playlist_rect = Some(construct_and_render_block(
"Playlists",
&ui.theme,
borders,
frame,
chunks[_chunk_index],
));
_chunk_index += 1;
}

if configs.app_config.layout.library.album_percent.is_some() {
let borders = if _chunk_index == total_sections - 1 {
Borders::ALL
} else {
Borders::TOP | Borders::LEFT | Borders::BOTTOM
};
album_rect = Some(construct_and_render_block(
"Albums",
&ui.theme,
borders,
frame,
chunks[_chunk_index],
));
_chunk_index += 1;
}

if configs.app_config.layout.library.artist_percent.is_some() {
let borders = Borders::ALL; // This will always be the last section if it exists
artist_rect = Some(construct_and_render_block(
"Artists",
&ui.theme,
borders,
frame,
chunks[_chunk_index],
));
}

// 3. Construct the page's widgets
// Construct the playlist window
let items = ui
.search_filtered_items(&data.user_data.folder_playlists_items(playlist_folder_id))
.into_iter()
.map(|item| match item {
PlaylistFolderItem::Playlist(p) => {
(p.to_string(), curr_context_uri == Some(p.id.uri()))
}
PlaylistFolderItem::Folder(f) => (f.to_string(), false),
})
.collect::<Vec<_>>();

let (playlist_list, n_playlists) = utils::construct_list_widget(
&ui.theme,
items,
is_active
&& focus_state != LibraryFocusState::SavedAlbums
&& focus_state != LibraryFocusState::FollowedArtists,
ui.search_filtered_items(&data.user_data.playlists)
.into_iter()
.map(|item| match item {
PlaylistFolderItem::Playlist(p) => {
(p.to_string(), curr_context_uri == Some(p.id.uri()))
}
PlaylistFolderItem::Folder(f) => (f.to_string(), false),
})
.collect(),
is_active && focus_state == LibraryFocusState::Playlists,
);
// Construct the saved album window
let (album_list, n_albums) = utils::construct_list_widget(
Expand Down Expand Up @@ -402,27 +434,35 @@ pub fn render_library_page(
_ => return,
};

utils::render_list_window(
frame,
playlist_list,
playlist_rect,
n_playlists,
&mut page_state.playlist_list,
);
utils::render_list_window(
frame,
album_list,
album_rect,
n_albums,
&mut page_state.saved_album_list,
);
utils::render_list_window(
frame,
artist_list,
artist_rect,
n_artists,
&mut page_state.followed_artist_list,
);
if let Some(rect) = playlist_rect {
utils::render_list_window(
frame,
playlist_list,
rect,
n_playlists,
&mut page_state.playlist_list,
);
}

if let Some(rect) = album_rect {
utils::render_list_window(
frame,
album_list,
rect,
n_albums,
&mut page_state.saved_album_list,
);
}

if let Some(rect) = artist_rect {
utils::render_list_window(
frame,
artist_list,
rect,
n_artists,
&mut page_state.followed_artist_list,
);
}
}

pub fn render_browse_page(
Expand Down

0 comments on commit dbc6e92

Please sign in to comment.