This commit is contained in:
2026-10-23 03:02:22 +07:00
parent 980ca18b60
commit 0879a8946a
20 changed files with 1827 additions and 960 deletions
+99 -20
View File
@@ -29,6 +29,8 @@ type ScreenSession struct {
TimerRemainingSeconds int64
TimerState int32
TimerEndsAt *time.Time
QRURL string
TimerType int32
Text string
}
@@ -55,20 +57,41 @@ func (r *ScreenSessionsRepo) Create(ctx context.Context, tokenHash string) (int,
// Get returns a screen session by ID and token hash.
func (r *ScreenSessionsRepo) Get(ctx context.Context, id int, tokenHash string) (*ScreenSession, error) {
session := &ScreenSession{ID: id}
err := r.pool.QueryRow(ctx, `
SELECT game_id, sound_enabled, last_seen_at, mode, state_version, position_ms, command, volume,
timer_label, timer_duration_seconds, timer_remaining_seconds, timer_state, timer_ends_at, text
err := r.pool.QueryRow(
ctx,
`SELECT
game_id,
sound_enabled,
last_seen_at,
mode,
state_version,
position_ms,
command,
volume,
timer_label,
timer_duration_seconds,
timer_remaining_seconds,
timer_state,
timer_ends_at,
text,
qr_url,
timer_type
FROM screen_sessions
WHERE id = $1 AND access_token_hash = $2`, id, tokenHash).
WHERE id = $1 AND access_token_hash = $2`,
id,
tokenHash,
).
Scan(&session.GameID, &session.Sound, &session.LastSeen, &session.Mode, &session.Version, &session.Position, &session.Command, &session.Volume,
&session.TimerLabel, &session.TimerDurationSeconds, &session.TimerRemainingSeconds, &session.TimerState, &session.TimerEndsAt, &session.Text)
&session.TimerLabel, &session.TimerDurationSeconds, &session.TimerRemainingSeconds, &session.TimerState, &session.TimerEndsAt, &session.Text, &session.QRURL, &session.TimerType)
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrScreenNotFound
}
if err != nil {
return nil, err
}
_, err = r.pool.Exec(ctx, `UPDATE screen_sessions SET last_seen_at = NOW() WHERE id = $1`, id)
_, err = r.pool.Exec(ctx, `UPDATE screen_sessions SET last_seen_at = NOW() WHERE id = $1`,
id,
)
if err != nil {
return nil, err
}
@@ -78,12 +101,31 @@ func (r *ScreenSessionsRepo) Get(ctx context.Context, id int, tokenHash string)
// ListByGame returns screen sessions for a game.
func (r *ScreenSessionsRepo) ListByGame(ctx context.Context, gameID int) ([]*ScreenSession, error) {
rows, err := r.pool.Query(ctx, `
SELECT id, game_id, sound_enabled, last_seen_at, mode, state_version, position_ms, command, volume,
timer_label, timer_duration_seconds, timer_remaining_seconds, timer_state, timer_ends_at, text
rows, err := r.pool.Query(
ctx,
`SELECT
id,
game_id,
sound_enabled,
last_seen_at,
mode,
state_version,
position_ms,
command,
volume,
timer_label,
timer_duration_seconds,
timer_remaining_seconds,
timer_state,
timer_ends_at,
text,
qr_url,
timer_type
FROM screen_sessions
WHERE game_id = $1
ORDER BY id`, gameID)
ORDER BY id`,
gameID,
)
if err != nil {
return nil, err
}
@@ -93,7 +135,7 @@ func (r *ScreenSessionsRepo) ListByGame(ctx context.Context, gameID int) ([]*Scr
for rows.Next() {
session := &ScreenSession{}
if err := rows.Scan(&session.ID, &session.GameID, &session.Sound, &session.LastSeen, &session.Mode, &session.Version, &session.Position, &session.Command, &session.Volume,
&session.TimerLabel, &session.TimerDurationSeconds, &session.TimerRemainingSeconds, &session.TimerState, &session.TimerEndsAt, &session.Text); err != nil {
&session.TimerLabel, &session.TimerDurationSeconds, &session.TimerRemainingSeconds, &session.TimerState, &session.TimerEndsAt, &session.Text, &session.QRURL, &session.TimerType); err != nil {
return nil, err
}
sessions = append(sessions, session)
@@ -148,10 +190,12 @@ func (r *ScreenSessionsRepo) SetCommand(ctx context.Context, gameID int, command
}
// SetTimer updates the display timer for a game.
func (r *ScreenSessionsRepo) SetTimer(ctx context.Context, gameID int, duration int64, label string) error {
_, err := r.pool.Exec(ctx, `
UPDATE screen_sessions
func (r *ScreenSessionsRepo) SetTimer(ctx context.Context, gameID int, duration int64, label string, timerType int32) error {
_, err := r.pool.Exec(
ctx,
`UPDATE screen_sessions
SET mode = 7,
timer_type = $4,
timer_label = $2,
timer_duration_seconds = $3,
timer_remaining_seconds = $3,
@@ -161,7 +205,12 @@ func (r *ScreenSessionsRepo) SetTimer(ctx context.Context, gameID int, duration
state_version = state_version + 1,
text = '',
updated_at = NOW()
WHERE game_id = $1`, gameID, label, duration)
WHERE game_id = $1`,
gameID,
label,
duration,
timerType,
)
return err
}
@@ -280,12 +329,15 @@ func (r *ScreenSessionsRepo) BindWithAudio(ctx context.Context, id, gameID int,
// Unbind detaches a screen session from its game.
func (r *ScreenSessionsRepo) Unbind(ctx context.Context, id int) error {
result, err := r.pool.Exec(ctx, `
UPDATE screen_sessions
result, err := r.pool.Exec(
ctx,
`UPDATE screen_sessions
SET game_id = NULL,
mode = 1,
command = 0,
position_ms = 0,
qr_url = '',
timer_type = 0,
timer_label = 'Перерыв',
timer_duration_seconds = 600,
timer_remaining_seconds = 600,
@@ -294,7 +346,9 @@ func (r *ScreenSessionsRepo) Unbind(ctx context.Context, id int) error {
text = '',
state_version = state_version + 1,
updated_at = NOW()
WHERE id = $1`, id)
WHERE id = $1`,
id,
)
if err != nil {
return err
}
@@ -339,12 +393,14 @@ func (r *ScreenSessionsRepo) SetSound(ctx context.Context, id int, enabled bool)
}
// InitializeScreen copies a live display or uses the plan for the first screen.
func (r *ScreenSessionsRepo) InitializeScreen(ctx context.Context, id, gameID int, mode int32, text, label string, duration int64) error {
func (r *ScreenSessionsRepo) InitializeScreen(ctx context.Context, id, gameID int, mode int32, text, label string, duration int64, qrURL string, timerType int32) error {
_, err := r.pool.Exec(
ctx,
`UPDATE screen_sessions target
SET mode = COALESCE(source.mode, $3),
text = COALESCE(source.text, $4),
qr_url = COALESCE(source.qr_url, $7),
timer_type = COALESCE(source.timer_type, $8),
command = COALESCE(source.command, 0),
position_ms = COALESCE(source.position_ms, 0),
timer_label = COALESCE(source.timer_label, $5),
@@ -365,7 +421,9 @@ func (r *ScreenSessionsRepo) InitializeScreen(ctx context.Context, id, gameID in
timer_duration_seconds,
timer_remaining_seconds,
timer_state,
timer_ends_at
timer_ends_at,
qr_url,
timer_type
FROM screen_sessions
WHERE game_id = $2 AND id <> $1
ORDER BY updated_at DESC, id DESC
@@ -378,6 +436,27 @@ func (r *ScreenSessionsRepo) InitializeScreen(ctx context.Context, id, gameID in
text,
label,
duration,
qrURL,
timerType,
)
return err
}
// SetQR updates QR content and mode together.
func (r *ScreenSessionsRepo) SetQR(ctx context.Context, gameID int, link, text string) error {
_, err := r.pool.Exec(
ctx,
`UPDATE screen_sessions
SET mode = 9,
qr_url = $2,
text = $3,
command = 0,
state_version = state_version + 1,
updated_at = NOW()
WHERE game_id = $1`,
gameID,
link,
text,
)
return err
}