Files
memby/server/internal/api/home_row_layout.go
T
2026-08-28 23:00:02 +12:00

79 lines
2.4 KiB
Go

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)))
}