package api import ( "context" "encoding/json" "strings" "github.com/ponzischeme89/memby/server/internal/config" "github.com/ponzischeme89/memby/server/internal/recommend" "github.com/ponzischeme89/memby/server/internal/store" ) // sectionDefinitionKeys are the three configuration values that hold a page's row // composition. A layout override can be set on any of them, and the home payload is the // single row source for all three browse destinations on the television, so all three are // merged into one lookup. var sectionDefinitionKeys = []string{ "home.sectionDefinitions", "movies.sectionDefinitions", "tv.sectionDefinitions", } // rowLayoutOverrides collects every operator-pinned card shape from the section // definitions, keyed by the definition id. An invalid or empty layout is not an override. func rowLayoutOverrides(policy store.FeaturePolicy) map[string]string { overrides := map[string]string{} for _, key := range sectionDefinitionKeys { raw, ok := policy.Values[key] if !ok { continue } var definitions []config.RemoteSectionDefinition if json.Unmarshal(raw, &definitions) != nil { continue } for _, definition := range definitions { switch definition.Layout { case config.SectionLayoutPoster, config.SectionLayoutThumb: id := strings.TrimSpace(definition.ID) if id != "" { overrides[id] = definition.Layout } } } } return overrides } // applyRowLayoutOverrides stamps the pinned card shape onto each finished row. A row is // matched by its exact id first, then by a section id it is a child of ("for-you" pins // "for-you:home:evening" too) — the same rule applyRemoteHomeSections uses on the // television to rank a family of rows together. A row that already carries a layout (none // do today) is left alone. Pure, so it can be pinned by a test. func applyRowLayoutOverrides(rows []recommend.Row, overrides map[string]string) []recommend.Row { if len(overrides) == 0 { return rows } for index := range rows { if rows[index].Layout != "" { continue } if layout, ok := overrides[rows[index].ID]; ok { rows[index].Layout = layout continue } for section, layout := range overrides { if strings.HasPrefix(rows[index].ID, section+":") { rows[index].Layout = layout break } } } return rows } func (s *Server) applyRowLayouts(ctx context.Context, rows []recommend.Row) []recommend.Row { return applyRowLayoutOverrides(rows, rowLayoutOverrides(s.currentFeaturePolicy(ctx))) }