feat(settings): add playback.intro_skip_mode and deprecate auto_skip_intro
Skipping intros stops being a switch and becomes a three-way choice —
never / ask / always — matching what Jellyfin offers and giving viewers a
way to turn the prompt off, which the boolean could not express.
Contract revision 6 → 7: adds playback.intro_skip_mode (enum, default
"ask", profile + profile_device scopes) and marks playback.auto_skip_intro
deprecated without removing it. Every shipped client still reads the
boolean, so for one release the server keeps the pair in step at write
time: canonical PUT/DELETE, the legacy /profiles route, and the legacy
runtime /settings/{key} route all land both rows, and a profile-scope enum
write refreshes user_profiles.auto_skip_intro so GET /profiles stays
truthful. Existing rows are carried onto the new key by a Goose migration
(Postgres) and an InitSchema twin (per-user SQLite); the settings-migrate
planner emits the companion for installs whose backfill runs later.
The spec in docs/design/2026-08-16-intro-skip-mode.md also defines the
prompt state machine every client (web, Android, Apple; browser, tablet,
mobile, TV) implements against this key. It builds on the Android TV
Skip Intro work in silo-android#210 — wall-clock timer, rebuffer-vs-pause
debounce, root-level key handling.
Co-authored-by: evulhotdog <365456+evulhotdog@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
evulhotdog
Claude Fable 5
parent
edd919c5f7
commit
af974edfe9
@@ -111,6 +111,20 @@ SELECT COUNT(*) FROM user_setting_values
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("auto_skip_intro carries its revision-7 replacement", func(t *testing.T) {
|
||||
var value string
|
||||
err := pool.QueryRow(ctx, `
|
||||
SELECT value::text FROM user_setting_values
|
||||
WHERE key = 'playback.intro_skip_mode' AND scope = 'profile' AND profile_id = 'mp1'`).
|
||||
Scan(&value)
|
||||
if err != nil {
|
||||
t.Fatalf("reading migrated intro_skip_mode: %v", err)
|
||||
}
|
||||
if value != `"always"` {
|
||||
t.Errorf("intro_skip_mode = %s, want \"always\"", value)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("metadata language migrates from the postgres-only column", func(t *testing.T) {
|
||||
var value string
|
||||
err := pool.QueryRow(ctx, `
|
||||
|
||||
Reference in New Issue
Block a user