feat(podcasts): unset listening order defaults to reversed (audiobook-first)

The per-feed listening order — the Order dropdown on the podcast page
and player — resolved its UNSET state to "native": feed document order,
which runs newest-first for classic RSS. This platform is audiobook-
first, so native started every book at its LAST chapter (verified on
live data: 7th Son position 1 = Bonus Episode #2, positions descending
through the chapters).

The unset fallback flips to "reverse" at every resolution site of that
ONE setting — the podcast page's list + dropdown (podcastOrderForFeed),
the player's feed chain (reader.go), and the download queue
(orderOverrideFor) — so the dropdown shows reversed selected, the page
renders in that order, and play/download follow. Stored overrides are
untouched (native stays a valid savable choice); no ordering semantics
changed; collections are untouched.

Pins: the flipped native expectation is changelogged in contract_pins;
new pins cover the sequence config carrying reverse, feed position 1
playing last, and the page dropdown rendering reverse selected for an
unset feed.
This commit is contained in:
John O'Keefe committed 2026-11-01 11:46:14 -05:00
1 parent 65f257f377
commit 0e29eff7b7
5 files changed
+65 -12

No files matched your search

+10 -3
View File
@@ -381,6 +381,13 @@ func buildPodcastDetailData(c *echo.Context, cfg *Config, user templates.User, f
}
// podcastOrderForFeed reads the caller's order override (D5).
//
// The UNSET default is "reverse" (2026-11-01 user request): the platform
// is audiobook-first and feed document order runs newest-first, so
// native starts a book at its LAST chapter. This is the same per-feed
// setting the Order dropdown shows — page list, player chain, and
// download queue all resolve through it. Stored overrides are untouched:
// anyone who picked an order keeps exactly what they picked.
func podcastOrderForFeed(cfg *Config, c *echo.Context, feedID string) string {
user := handlers.MustGetAuthenticatedUser(c)
row, err := cfg.Queries.GetUserSettingByKey(c.Request().Context(), database.GetUserSettingByKeyParams{
@@ -388,16 +395,16 @@ func podcastOrderForFeed(cfg *Config, c *echo.Context, feedID string) string {
SettingKey: "podcast_order:" + feedID,
})
if err != nil {
return "native"
return "reverse"
}
var v struct {
Order string `json:"order"`
}
if err := json.Unmarshal(row, &v); err != nil {
return "native"
return "reverse"
}
if !services.ValidPodcastEpisodeOrder(v.Order) {
return "native"
return "reverse"
}
return v.Order
}
+5 -2
View File
@@ -187,8 +187,11 @@ func buildPodcastSequenceContext(c *echo.Context, cfg *Config, item *database.Me
return nil
}
// Effective order override (D5): reader_settings KV.
order := "native"
// Effective order override (D5): reader_settings KV. UNSET defaults
// to "reverse" (2026-11-01: audiobook-first — native document order
// starts a book at its last chapter); the same default the podcast
// page's Order dropdown shows. Stored overrides are untouched.
order := "reverse"
if row, err := cfg.Queries.GetUserSettingByKey(ctx, database.GetUserSettingByKeyParams{
UserID: userID,
SettingKey: "podcast_order:" + uuid.UUID(item.SourceFeedID.Bytes).String(),