Remember selected season when refreshing season list (fixes #59)
This commit is contained in:
@@ -16,7 +16,9 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
display_years::DisplayYears, media_details_header::MediaDetailsHeader, seasons::Seasons,
|
display_years::DisplayYears,
|
||||||
|
media_details_header::MediaDetailsHeader,
|
||||||
|
seasons::{Seasons, SeasonsOutput},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct MediaDetailsContents {
|
pub struct MediaDetailsContents {
|
||||||
@@ -25,11 +27,13 @@ pub struct MediaDetailsContents {
|
|||||||
series_id: Option<Uuid>,
|
series_id: Option<Uuid>,
|
||||||
header: OnceCell<Controller<MediaDetailsHeader>>,
|
header: OnceCell<Controller<MediaDetailsHeader>>,
|
||||||
seasons: Option<AsyncController<Seasons>>,
|
seasons: Option<AsyncController<Seasons>>,
|
||||||
|
selected_season_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MediaDetailsContentsInput {
|
pub enum MediaDetailsContentsInput {
|
||||||
RefreshSeasons,
|
RefreshSeasons,
|
||||||
|
SetSelectedSeasonIndex(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub async)]
|
#[relm4::component(pub async)]
|
||||||
@@ -92,7 +96,7 @@ impl AsyncComponent for MediaDetailsContents {
|
|||||||
async fn init(
|
async fn init(
|
||||||
init: Self::Init,
|
init: Self::Init,
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
_sender: AsyncComponentSender<Self>,
|
sender: AsyncComponentSender<Self>,
|
||||||
) -> AsyncComponentParts<Self> {
|
) -> AsyncComponentParts<Self> {
|
||||||
let (api_client, media) = init;
|
let (api_client, media) = init;
|
||||||
|
|
||||||
@@ -115,6 +119,7 @@ impl AsyncComponent for MediaDetailsContents {
|
|||||||
series_id,
|
series_id,
|
||||||
header: OnceCell::new(),
|
header: OnceCell::new(),
|
||||||
seasons: None,
|
seasons: None,
|
||||||
|
selected_season_index: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
@@ -133,7 +138,7 @@ impl AsyncComponent for MediaDetailsContents {
|
|||||||
|
|
||||||
model.add_info(info_box);
|
model.add_info(info_box);
|
||||||
|
|
||||||
model.load_seasons(container);
|
model.load_seasons(&sender, container);
|
||||||
|
|
||||||
AsyncComponentParts { model, widgets }
|
AsyncComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
@@ -147,7 +152,10 @@ impl AsyncComponent for MediaDetailsContents {
|
|||||||
) {
|
) {
|
||||||
match message {
|
match message {
|
||||||
MediaDetailsContentsInput::RefreshSeasons => {
|
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);
|
self.update_view(widgets, sender);
|
||||||
@@ -155,7 +163,7 @@ impl AsyncComponent for MediaDetailsContents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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() {
|
if let Some(seasons) = self.seasons.take() {
|
||||||
container.remove(seasons.widget());
|
container.remove(seasons.widget());
|
||||||
}
|
}
|
||||||
@@ -165,8 +173,9 @@ impl MediaDetailsContents {
|
|||||||
.launch(SeasonsInit {
|
.launch(SeasonsInit {
|
||||||
api_client: self.api_client.clone(),
|
api_client: self.api_client.clone(),
|
||||||
series_id,
|
series_id,
|
||||||
|
initial_selected_season_index: self.selected_season_index,
|
||||||
})
|
})
|
||||||
.detach();
|
.forward(sender.input_sender(), |m| m.into());
|
||||||
container.append(seasons.widget());
|
container.append(seasons.widget());
|
||||||
self.seasons = Some(seasons);
|
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))]
|
#[relm4::component(pub(crate))]
|
||||||
impl SimpleComponent for SeasonButtons {
|
impl SimpleComponent for SeasonButtons {
|
||||||
type Init = Vec<BaseItemDto>;
|
type Init = (Vec<BaseItemDto>, usize);
|
||||||
type Input = ();
|
type Input = ();
|
||||||
type Output = SeasonsInput;
|
type Output = SeasonsInput;
|
||||||
|
|
||||||
@@ -23,10 +23,12 @@ impl SimpleComponent for SeasonButtons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
seasons: Self::Init,
|
init: Self::Init,
|
||||||
seasons_box: &Self::Root,
|
seasons_box: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
|
let (seasons, initial_selected_season_index) = init;
|
||||||
|
|
||||||
let model = SeasonButtons;
|
let model = SeasonButtons;
|
||||||
|
|
||||||
let widgets = view_output!();
|
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]);
|
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));
|
first_btn.connect_toggled(btn_toggle_handler(0));
|
||||||
seasons_box.append(&first_btn);
|
seasons_box.append(&first_btn);
|
||||||
|
|
||||||
for (index, season) in seasons.iter().enumerate().skip(1) {
|
for (index, season) in seasons.iter().enumerate().skip(1) {
|
||||||
let season_btn = create_season_btn(season);
|
let season_btn = create_season_btn(season);
|
||||||
season_btn.set_group(Some(&first_btn));
|
season_btn.set_group(Some(&first_btn));
|
||||||
|
season_btn.set_active(initial_selected_season_index == index);
|
||||||
season_btn.connect_toggled(btn_toggle_handler(index));
|
season_btn.connect_toggled(btn_toggle_handler(index));
|
||||||
seasons_box.append(&season_btn);
|
seasons_box.append(&season_btn);
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ pub struct Seasons {
|
|||||||
pub struct SeasonsInit {
|
pub struct SeasonsInit {
|
||||||
pub api_client: Arc<ApiClient>,
|
pub api_client: Arc<ApiClient>,
|
||||||
pub series_id: Uuid,
|
pub series_id: Uuid,
|
||||||
|
pub initial_selected_season_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -33,11 +34,16 @@ pub enum SeasonsInput {
|
|||||||
SeasonActivated(usize),
|
SeasonActivated(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SeasonsOutput {
|
||||||
|
SeasonSelected(usize),
|
||||||
|
}
|
||||||
|
|
||||||
#[relm4::component(pub async)]
|
#[relm4::component(pub async)]
|
||||||
impl AsyncComponent for Seasons {
|
impl AsyncComponent for Seasons {
|
||||||
type Init = SeasonsInit;
|
type Init = SeasonsInit;
|
||||||
type Input = SeasonsInput;
|
type Input = SeasonsInput;
|
||||||
type Output = ();
|
type Output = SeasonsOutput;
|
||||||
type CommandOutput = ();
|
type CommandOutput = ();
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
@@ -74,6 +80,7 @@ impl AsyncComponent for Seasons {
|
|||||||
let SeasonsInit {
|
let SeasonsInit {
|
||||||
api_client,
|
api_client,
|
||||||
series_id,
|
series_id,
|
||||||
|
initial_selected_season_index,
|
||||||
} = init;
|
} = init;
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
@@ -93,14 +100,18 @@ impl AsyncComponent for Seasons {
|
|||||||
return AsyncComponentParts { model, widgets };
|
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()
|
let season_buttons = SeasonButtons::builder()
|
||||||
.launch(model.seasons.clone())
|
.launch((model.seasons.clone(), initial_selected_season_index))
|
||||||
.forward(sender.input_sender(), |e| e);
|
.forward(sender.input_sender(), |e| e);
|
||||||
root.append(season_buttons.widget());
|
root.append(season_buttons.widget());
|
||||||
model.season_buttons = Some(season_buttons);
|
model.season_buttons = Some(season_buttons);
|
||||||
|
|
||||||
// Load first season by default
|
sender.input(SeasonsInput::SeasonActivated(initial_selected_season_index));
|
||||||
sender.input(SeasonsInput::SeasonActivated(0));
|
|
||||||
|
|
||||||
AsyncComponentParts { model, widgets }
|
AsyncComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
@@ -108,7 +119,7 @@ impl AsyncComponent for Seasons {
|
|||||||
async fn update(
|
async fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: Self::Input,
|
msg: Self::Input,
|
||||||
_sender: AsyncComponentSender<Self>,
|
sender: AsyncComponentSender<Self>,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
) {
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
@@ -128,6 +139,8 @@ impl AsyncComponent for Seasons {
|
|||||||
.detach();
|
.detach();
|
||||||
root.append(episodes.widget());
|
root.append(episodes.widget());
|
||||||
self.episodes = Some(episodes);
|
self.episodes = Some(episodes);
|
||||||
|
|
||||||
|
sender.output(SeasonsOutput::SeasonSelected(index)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user