diff --git a/src/headless_engine/contracts.rs b/src/headless_engine/contracts.rs index a218793..2066147 100644 --- a/src/headless_engine/contracts.rs +++ b/src/headless_engine/contracts.rs @@ -235,6 +235,14 @@ pub(super) enum AppAction { profile: Option, language: Option, }, + #[serde(rename = "discoverPageRequested")] + DiscoverPageRequested { + transport_url: Option, + content_type: String, + catalog_id: String, + skip: Option, + genre: Option, + }, #[serde(rename = "catalogPageRequested")] CatalogPageRequested { category_id: String, diff --git a/src/headless_engine/discover.rs b/src/headless_engine/discover.rs index 617a093..19202a9 100644 --- a/src/headless_engine/discover.rs +++ b/src/headless_engine/discover.rs @@ -18,6 +18,25 @@ pub(super) struct DiscoverState { genres: Value, error: Value, generation: u64, + paging: DiscoverPaging, +} + +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)] +#[serde(rename_all = "camelCase", default)] +pub(super) struct DiscoverPaging { + is_loading: bool, + items: Value, + error: Value, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct FetchDiscoverPagePayload { + transport_url: Option, + content_type: String, + catalog_id: String, + skip: i32, + genre: Option, } #[derive(Serialize)] @@ -48,6 +67,7 @@ pub(super) fn dispatch_discover( language: Option, ) -> Vec { let generation = engine.bump_generation(GenerationKey::Discover); + engine.bump_generation(GenerationKey::DiscoverPaging); let profile_value = profile.unwrap_or_else(|| engine.state.profile.active.clone()); let profile_id = active_profile_id(&engine.state, &profile_value); let filters_value = filters.unwrap_or(Value::Null); @@ -62,6 +82,7 @@ pub(super) fn dispatch_discover( genres: engine.state.discover.genres.clone(), error: Value::Null, generation, + paging: DiscoverPaging::default(), }; vec![engine.effect( EffectKind::RunDiscover, @@ -102,6 +123,33 @@ pub(super) fn dispatch_catalog_filters( )] } +pub(super) fn dispatch_discover_page( + engine: &mut HeadlessEngine, + transport_url: Option, + content_type: String, + catalog_id: String, + skip: Option, + genre: Option, +) -> Vec { + let generation = engine.bump_generation(GenerationKey::DiscoverPaging); + engine.state.discover.paging = DiscoverPaging { + is_loading: true, + items: Value::Null, + error: Value::Null, + }; + vec![engine.effect( + EffectKind::FetchDiscoverPage, + generation, + FetchDiscoverPagePayload { + transport_url, + content_type, + catalog_id, + skip: skip.unwrap_or(0).max(0), + genre, + }, + )] +} + pub(super) fn complete( engine: &mut HeadlessEngine, effect_type: &str, @@ -149,6 +197,21 @@ pub(super) fn complete( } } } + "fetchDiscoverPage" => { + if generation == engine.state.runtime.get(GenerationKey::DiscoverPaging) { + engine.state.discover.paging.is_loading = false; + if result.status.is_ok() { + engine.state.discover.paging.items = result + .value + .get("items") + .cloned() + .unwrap_or_else(|| serde_json::json!([])); + engine.state.discover.paging.error = Value::Null; + } else { + engine.state.discover.paging.error = normalize_error(result.error.clone()); + } + } + } _ => {} } vec![] diff --git a/src/headless_engine/mod.rs b/src/headless_engine/mod.rs index 144ef76..5c042ff 100644 --- a/src/headless_engine/mod.rs +++ b/src/headless_engine/mod.rs @@ -442,6 +442,20 @@ impl HeadlessEngine { profile, language, ), + AppAction::DiscoverPageRequested { + transport_url, + content_type, + catalog_id, + skip, + genre, + } => discover::dispatch_discover_page( + self, + transport_url, + content_type, + catalog_id, + skip, + genre, + ), AppAction::CatalogPageRequested { category_id, transport_url, @@ -605,7 +619,9 @@ impl HeadlessEngine { EffectKind::RunSearch => search::complete(self, generation, &result), - EffectKind::RunDiscover | EffectKind::ReadDiscoverCatalogFilters => { + EffectKind::RunDiscover + | EffectKind::ReadDiscoverCatalogFilters + | EffectKind::FetchDiscoverPage => { discover::complete(self, effect_type, generation, &result) } diff --git a/src/headless_engine/state.rs b/src/headless_engine/state.rs index 9229fe4..951bcd2 100644 --- a/src/headless_engine/state.rs +++ b/src/headless_engine/state.rs @@ -89,6 +89,7 @@ pub(super) enum GenerationKey { Addon, Search, Discover, + DiscoverPaging, Sync, Auth, Settings, @@ -110,6 +111,7 @@ pub(super) struct RuntimeGenerations { addon_generation: u64, search_generation: u64, discover_generation: u64, + discover_paging_generation: u64, sync_generation: u64, auth_generation: u64, settings_generation: u64, @@ -131,6 +133,7 @@ impl RuntimeGenerations { GenerationKey::Addon => self.addon_generation, GenerationKey::Search => self.search_generation, GenerationKey::Discover => self.discover_generation, + GenerationKey::DiscoverPaging => self.discover_paging_generation, GenerationKey::Sync => self.sync_generation, GenerationKey::Auth => self.auth_generation, GenerationKey::Settings => self.settings_generation, @@ -152,6 +155,7 @@ impl RuntimeGenerations { GenerationKey::Addon => &mut self.addon_generation, GenerationKey::Search => &mut self.search_generation, GenerationKey::Discover => &mut self.discover_generation, + GenerationKey::DiscoverPaging => &mut self.discover_paging_generation, GenerationKey::Sync => &mut self.sync_generation, GenerationKey::Auth => &mut self.auth_generation, GenerationKey::Settings => &mut self.settings_generation, diff --git a/src/runtime/effects.rs b/src/runtime/effects.rs index a16051e..e2ddac1 100644 --- a/src/runtime/effects.rs +++ b/src/runtime/effects.rs @@ -15,6 +15,7 @@ pub enum EffectKind { FetchAddonManifest, FetchAddonResource, FetchCatalogPage, + FetchDiscoverPage, FetchDetailSecondary, FetchDetailStreams, FetchIntroSegments, @@ -63,6 +64,7 @@ impl EffectKind { EffectKind::FetchAddonManifest => "fetchAddonManifest", EffectKind::FetchAddonResource => "fetchAddonResource", EffectKind::FetchCatalogPage => "fetchCatalogPage", + EffectKind::FetchDiscoverPage => "fetchDiscoverPage", EffectKind::FetchDetailSecondary => "fetchDetailSecondary", EffectKind::FetchDetailStreams => "fetchDetailStreams", EffectKind::FetchIntroSegments => "fetchIntroSegments", @@ -112,6 +114,7 @@ impl EffectKind { "fetchAddonManifest" => EffectKind::FetchAddonManifest, "fetchAddonResource" => EffectKind::FetchAddonResource, "fetchCatalogPage" => EffectKind::FetchCatalogPage, + "fetchDiscoverPage" => EffectKind::FetchDiscoverPage, "fetchDetailSecondary" => EffectKind::FetchDetailSecondary, "fetchDetailStreams" => EffectKind::FetchDetailStreams, "fetchIntroSegments" => EffectKind::FetchIntroSegments, @@ -212,6 +215,7 @@ mod tests { EffectKind::FetchAddonManifest, EffectKind::FetchAddonResource, EffectKind::FetchCatalogPage, + EffectKind::FetchDiscoverPage, EffectKind::FetchDetailSecondary, EffectKind::FetchDetailStreams, EffectKind::FetchIntroSegments,