Remember selected season when refreshing season list (fixes #59)

This commit is contained in:
Avery
2024-01-18 00:19:04 -05:00
parent e6deee77e9
commit 222cf8e24e
3 changed files with 50 additions and 15 deletions

View File

@@ -16,7 +16,9 @@ use crate::{
};
use super::{
display_years::DisplayYears, media_details_header::MediaDetailsHeader, seasons::Seasons,
display_years::DisplayYears,
media_details_header::MediaDetailsHeader,
seasons::{Seasons, SeasonsOutput},
};
pub struct MediaDetailsContents {
@@ -25,11 +27,13 @@ pub struct MediaDetailsContents {
series_id: Option<Uuid>,
header: OnceCell<Controller<MediaDetailsHeader>>,
seasons: Option<AsyncController<Seasons>>,
selected_season_index: Option<usize>,
}
#[derive(Debug)]
pub enum MediaDetailsContentsInput {
RefreshSeasons,
SetSelectedSeasonIndex(usize),
}
#[relm4::component(pub async)]
@@ -92,7 +96,7 @@ impl AsyncComponent for MediaDetailsContents {
async fn init(
init: Self::Init,
root: Self::Root,
_sender: AsyncComponentSender<Self>,
sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
let (api_client, media) = init;
@@ -115,6 +119,7 @@ impl AsyncComponent for MediaDetailsContents {
series_id,
header: OnceCell::new(),
seasons: None,
selected_season_index: None,
};
let widgets = view_output!();
@@ -133,7 +138,7 @@ impl AsyncComponent for MediaDetailsContents {
model.add_info(info_box);
model.load_seasons(container);
model.load_seasons(&sender, container);
AsyncComponentParts { model, widgets }
}
@@ -147,7 +152,10 @@ impl AsyncComponent for MediaDetailsContents {
) {
match message {
MediaDetailsContentsInput::RefreshSeasons => {
self.load_seasons(&widgets.container);
self.load_seasons(&sender, &widgets.container);
}
MediaDetailsContentsInput::SetSelectedSeasonIndex(selected_season_index) => {
self.selected_season_index = Some(selected_season_index);
}
}
self.update_view(widgets, sender);
@@ -155,7 +163,7 @@ impl AsyncComponent for MediaDetailsContents {
}
impl MediaDetailsContents {
fn load_seasons(&mut self, container: &gtk::Box) {
fn load_seasons(&mut self, sender: &AsyncComponentSender<Self>, container: &gtk::Box) {
if let Some(seasons) = self.seasons.take() {
container.remove(seasons.widget());
}
@@ -165,8 +173,9 @@ impl MediaDetailsContents {
.launch(SeasonsInit {
api_client: self.api_client.clone(),
series_id,
initial_selected_season_index: self.selected_season_index,
})
.detach();
.forward(sender.input_sender(), |m| m.into());
container.append(seasons.widget());
self.seasons = Some(seasons);
}
@@ -232,3 +241,13 @@ impl MediaDetailsContents {
}
}
}
impl From<SeasonsOutput> for MediaDetailsContentsInput {
fn from(val: SeasonsOutput) -> Self {
match val {
SeasonsOutput::SeasonSelected(selected_season_index) => {
MediaDetailsContentsInput::SetSelectedSeasonIndex(selected_season_index)
}
}
}
}

View File

@@ -10,7 +10,7 @@ pub(crate) struct SeasonButtons;
#[relm4::component(pub(crate))]
impl SimpleComponent for SeasonButtons {
type Init = Vec<BaseItemDto>;
type Init = (Vec<BaseItemDto>, usize);
type Input = ();
type Output = SeasonsInput;
@@ -23,10 +23,12 @@ impl SimpleComponent for SeasonButtons {
}
fn init(
seasons: Self::Init,
init: Self::Init,
seasons_box: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let (seasons, initial_selected_season_index) = init;
let model = SeasonButtons;
let widgets = view_output!();
@@ -40,15 +42,16 @@ impl SimpleComponent for SeasonButtons {
}
};
// First button will be active and is used to group remaining buttons
// First button will is used to group remaining buttons
let first_btn = create_season_btn(&seasons[0]);
first_btn.set_active(true);
first_btn.set_active(initial_selected_season_index == 0);
first_btn.connect_toggled(btn_toggle_handler(0));
seasons_box.append(&first_btn);
for (index, season) in seasons.iter().enumerate().skip(1) {
let season_btn = create_season_btn(season);
season_btn.set_group(Some(&first_btn));
season_btn.set_active(initial_selected_season_index == index);
season_btn.connect_toggled(btn_toggle_handler(index));
seasons_box.append(&season_btn);
}

View File

@@ -26,6 +26,7 @@ pub struct Seasons {
pub struct SeasonsInit {
pub api_client: Arc<ApiClient>,
pub series_id: Uuid,
pub initial_selected_season_index: Option<usize>,
}
#[derive(Debug)]
@@ -33,11 +34,16 @@ pub enum SeasonsInput {
SeasonActivated(usize),
}
#[derive(Debug)]
pub enum SeasonsOutput {
SeasonSelected(usize),
}
#[relm4::component(pub async)]
impl AsyncComponent for Seasons {
type Init = SeasonsInit;
type Input = SeasonsInput;
type Output = ();
type Output = SeasonsOutput;
type CommandOutput = ();
view! {
@@ -74,6 +80,7 @@ impl AsyncComponent for Seasons {
let SeasonsInit {
api_client,
series_id,
initial_selected_season_index,
} = init;
let widgets = view_output!();
@@ -93,14 +100,18 @@ impl AsyncComponent for Seasons {
return AsyncComponentParts { model, widgets };
}
let initial_selected_season_index = match initial_selected_season_index {
Some(season) if season < model.seasons.len() => season,
_ => 0,
};
let season_buttons = SeasonButtons::builder()
.launch(model.seasons.clone())
.launch((model.seasons.clone(), initial_selected_season_index))
.forward(sender.input_sender(), |e| e);
root.append(season_buttons.widget());
model.season_buttons = Some(season_buttons);
// Load first season by default
sender.input(SeasonsInput::SeasonActivated(0));
sender.input(SeasonsInput::SeasonActivated(initial_selected_season_index));
AsyncComponentParts { model, widgets }
}
@@ -108,7 +119,7 @@ impl AsyncComponent for Seasons {
async fn update(
&mut self,
msg: Self::Input,
_sender: AsyncComponentSender<Self>,
sender: AsyncComponentSender<Self>,
root: &Self::Root,
) {
match msg {
@@ -128,6 +139,8 @@ impl AsyncComponent for Seasons {
.detach();
root.append(episodes.widget());
self.episodes = Some(episodes);
sender.output(SeasonsOutput::SeasonSelected(index)).unwrap();
}
}
}