Remember selected season when refreshing season list (fixes #59)
This commit is contained in:
@@ -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: >k::Box) {
|
||||
fn load_seasons(&mut self, sender: &AsyncComponentSender<Self>, container: >k::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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user