feat(podcasts): reverse order — position DESC, date-agnostic; single order helper
The 'Oldest first' order sorts by PUB DATE, which breaks on Scribl's migrated podiobooks feeds (messy/all-equal dates). New order value 'reverse' = feed position DESC with a date-DESC tiebreak — dates are not involved, so nothing can break. - services.OrderEpisodes: THE single order source of truth (§0 items 3+5a). The four surfaces (sequence JSON, reader chain context, SSR page list) previously carried three near-identical handwritten comparators — all now route through one generic helper. The SSR page list gains a SortDate key (lexical 2006-01-02) so the pub-date tiebreak is actually chronological; the old comparator compared 'Jan 2, 2006' display strings alphabetically (latent drift bug). - Dropdown becomes four options: Feed order / Feed order (reversed) / Oldest first (pub date) / Newest first (pub date). - Serial suggestion button renamed 'Reverse feed order' (sets reverse, not oldest) and its response out-of-band-swaps the order select (PodcastOrderSelectOOB — same mechanism as Download All's policy select), so the dropdown mirrors the server state immediately. - Validation: oneof=native reverse oldest newest everywhere. - Tests: reverse binds via the form wire; messy-dates sequence returns 3,2,1; existing reorder-safety stays green.
This commit is contained in:
1 parent
7c7c08748e
commit
e3675536aa
9 files changed
+708
-463
No files matched your search
@@ -9,9 +9,7 @@ import (
|
||||
"bookhoard/templates"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -186,7 +184,7 @@ func buildPodcastSequenceContext(c *echo.Context, cfg *Config, item *database.Me
|
||||
var v struct {
|
||||
Order string `json:"order"`
|
||||
}
|
||||
if json.Unmarshal(row, &v) == nil && (v.Order == "oldest" || v.Order == "newest") {
|
||||
if json.Unmarshal(row, &v) == nil && services.ValidPodcastEpisodeOrder(v.Order) {
|
||||
order = v.Order
|
||||
}
|
||||
}
|
||||
@@ -215,17 +213,11 @@ func buildPodcastSequenceContext(c *echo.Context, cfg *Config, item *database.Me
|
||||
pos: ep.FeedPosition.Int32,
|
||||
})
|
||||
}
|
||||
sort.SliceStable(ordered, func(a, b int) bool {
|
||||
ka := ordered[a].date + fmt.Sprintf("%06d", ordered[a].pos)
|
||||
kb := ordered[b].date + fmt.Sprintf("%06d", ordered[b].pos)
|
||||
if order == "newest" {
|
||||
return ka > kb
|
||||
}
|
||||
if order == "oldest" {
|
||||
return ka < kb
|
||||
}
|
||||
return ordered[a].pos < ordered[b].pos
|
||||
})
|
||||
// Effective listening order (order consolidation §0 item 5a).
|
||||
services.OrderEpisodes(ordered, order,
|
||||
func(e seqEp) int32 { return e.pos },
|
||||
func(e seqEp) string { return e.date },
|
||||
)
|
||||
|
||||
idx := -1
|
||||
for i, ep := range ordered {
|
||||
|
||||
Reference in new issue
Block a user