Issue #319: Infinite Play toggle had no backend wiring after the V2
migration — toggle only wrote to localStorage and the queue-end handler
ignored it, so playback stopped at the last track.
Reimplemented in V2 (no legacy wrappers):
- New `v2_create_infinite_radio` command that takes the last few played
track IDs, uses the most recent track's artist as the radio seed via
`RadioPoolBuilder::create_artist_radio` (Qobuz `/radio/artist`
endpoint), and returns 50 V2QueueTrack ready to append. Does NOT
mutate the queue or playback context — caller decides how to use them.
- `playbackPreferencesStore`: expose `'infinite'` in `AutoplayMode`
type and add `isInfinitePlayEnabled()` helper.
- `+page.svelte`:
- `handleToggleInfinitePlay` now syncs to backend via
`setAutoplayMode('infinite' | 'continue')` so the choice persists
in `playback_preferences.db` across restarts (was localStorage only).
- On startup load infinite play from cached preferences (was
localStorage).
- When `nextTrack()` returns null AND infinite play is on: collect
the current track + last 5 history tracks, call
`v2_create_infinite_radio`, append the result via
`v2_bulk_add_to_queue`, then advance — playback continues without
interruption.
i18n: add `toast.failedToSavePreference` to all 5 locales.
cc