feat(users): audio_resume_rewind_seconds column
Per-user resume rewind for the audiobook/podcast player: how many
seconds (0/5/10) before the saved position playback starts, both on
open-resume and again on every genuine unpause. Motivated by the car
startup case — exact resume loses the listener's place, and the
PlaybackRequestResolver path (phone UI, Android Auto, media buttons)
all funnel through one start position.
0 = exact resume (default), so the column is inert until the profile
page sets it. Follows the default_audio_speed / keep_screen_awake
precedent: idempotent ALTER in schema.sql (re-runs on every boot),
explicit GetUser SELECT, dedicated :exec update. Handler-side strict
allow-list {0,5,10} lands with the API slice.
This commit is contained in:
1 parent
0d613ba0e3
commit
daffe499eb
5 files changed
+61
-29
No files matched your search
@@ -11407,26 +11407,28 @@ SELECT
|
||||
u.timezone,
|
||||
u.default_audio_speed,
|
||||
u.keep_screen_awake,
|
||||
u.audio_resume_rewind_seconds,
|
||||
(SELECT COUNT(*) FROM devices WHERE user_id = u.id) as device_count
|
||||
FROM users u
|
||||
WHERE u.id = $1
|
||||
`
|
||||
|
||||
type GetUserRow struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Email string `db:"email" json:"email"`
|
||||
Username string `db:"username" json:"username"`
|
||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||
Role string `db:"role" json:"role"`
|
||||
MaxDevices pgtype.Int4 `db:"max_devices" json:"max_devices"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
Timezone pgtype.Text `db:"timezone" json:"timezone"`
|
||||
DefaultAudioSpeed float32 `db:"default_audio_speed" json:"default_audio_speed"`
|
||||
KeepScreenAwake bool `db:"keep_screen_awake" json:"keep_screen_awake"`
|
||||
DeviceCount int64 `db:"device_count" json:"device_count"`
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Email string `db:"email" json:"email"`
|
||||
Username string `db:"username" json:"username"`
|
||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||
Role string `db:"role" json:"role"`
|
||||
MaxDevices pgtype.Int4 `db:"max_devices" json:"max_devices"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
Timezone pgtype.Text `db:"timezone" json:"timezone"`
|
||||
DefaultAudioSpeed float32 `db:"default_audio_speed" json:"default_audio_speed"`
|
||||
KeepScreenAwake bool `db:"keep_screen_awake" json:"keep_screen_awake"`
|
||||
AudioResumeRewindSeconds int32 `db:"audio_resume_rewind_seconds" json:"audio_resume_rewind_seconds"`
|
||||
DeviceCount int64 `db:"device_count" json:"device_count"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetUser(ctx context.Context, id pgtype.UUID) (GetUserRow, error) {
|
||||
@@ -11446,6 +11448,7 @@ func (q *Queries) GetUser(ctx context.Context, id pgtype.UUID) (GetUserRow, erro
|
||||
&i.Timezone,
|
||||
&i.DefaultAudioSpeed,
|
||||
&i.KeepScreenAwake,
|
||||
&i.AudioResumeRewindSeconds,
|
||||
&i.DeviceCount,
|
||||
)
|
||||
return i, err
|
||||
@@ -20287,6 +20290,20 @@ func (q *Queries) UpdateUniversalProgress(ctx context.Context, arg UpdateUnivers
|
||||
return i, err
|
||||
}
|
||||
|
||||
const UpdateUserAudioResumeRewind = `-- name: UpdateUserAudioResumeRewind :exec
|
||||
UPDATE users SET audio_resume_rewind_seconds = $2, updated_at = NOW() WHERE id = $1
|
||||
`
|
||||
|
||||
type UpdateUserAudioResumeRewindParams struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
AudioResumeRewindSeconds int32 `db:"audio_resume_rewind_seconds" json:"audio_resume_rewind_seconds"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateUserAudioResumeRewind(ctx context.Context, arg UpdateUserAudioResumeRewindParams) error {
|
||||
_, err := q.db.Exec(ctx, UpdateUserAudioResumeRewind, arg.ID, arg.AudioResumeRewindSeconds)
|
||||
return err
|
||||
}
|
||||
|
||||
const UpdateUserDefaultAudioSpeed = `-- name: UpdateUserDefaultAudioSpeed :exec
|
||||
UPDATE users SET default_audio_speed = $2, updated_at = NOW() WHERE id = $1
|
||||
`
|
||||
@@ -20317,7 +20334,7 @@ func (q *Queries) UpdateUserKeepScreenAwake(ctx context.Context, arg UpdateUserK
|
||||
|
||||
const UpdateUserMaxDevices = `-- name: UpdateUserMaxDevices :one
|
||||
UPDATE users SET max_devices = $2, updated_at = NOW() WHERE id = $1
|
||||
RETURNING id, email, username, password_hash, first_name, last_name, role, theme, max_devices, created_at, timezone, updated_at, default_audio_speed, keep_screen_awake
|
||||
RETURNING id, email, username, password_hash, first_name, last_name, role, theme, max_devices, created_at, timezone, updated_at, default_audio_speed, keep_screen_awake, audio_resume_rewind_seconds
|
||||
`
|
||||
|
||||
type UpdateUserMaxDevicesParams struct {
|
||||
@@ -20343,6 +20360,7 @@ func (q *Queries) UpdateUserMaxDevices(ctx context.Context, arg UpdateUserMaxDev
|
||||
&i.UpdatedAt,
|
||||
&i.DefaultAudioSpeed,
|
||||
&i.KeepScreenAwake,
|
||||
&i.AudioResumeRewindSeconds,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user