Tabellone, badge e brand sono ricodificati nel flusso _air via OverlayRelay; sync punteggio HTTP, volume condiviso rails/sidekiq, qualità 720p migliorata e badge CONNECTING in ripresa da pausa. Co-authored-by: Cursor <cursoragent@cursor.com>
82 lines
2.5 KiB
Ruby
82 lines
2.5 KiB
Ruby
module Public
|
|
class RegiaController < SiteBaseController
|
|
include Public::LiveHelper
|
|
include MediamtxPlayback
|
|
|
|
layout "regia"
|
|
|
|
protect_from_forgery with: :null_session
|
|
skip_before_action :verify_authenticity_token, only: %i[score pause stop]
|
|
|
|
before_action :set_session_from_token
|
|
|
|
def show
|
|
@match = @session.match
|
|
@team = @match.team
|
|
@score = @session.score_state || @session.create_score_state!(
|
|
home_sets: 0, away_sets: 0, home_points: 0, away_points: 0, current_set: 1, set_partials: []
|
|
)
|
|
@rules = Scoring::Rules.from_match(@match)
|
|
@stream_closed = @session.terminal?
|
|
@on_air = !@stream_closed && mediamtx_stream_playable?(@session)
|
|
@share_url = request.original_url
|
|
@share_title = "Regia — #{@team.name} vs #{@match.opponent_name}"
|
|
end
|
|
|
|
def status
|
|
render json: status_payload
|
|
end
|
|
|
|
def score
|
|
cmd = params[:cmd].presence || params[:score_action].presence
|
|
result = Scoring::ApplyAction.new(session: @session, action: cmd).call
|
|
render json: status_payload.merge(
|
|
set_won: result.set_won,
|
|
match_won: result.match_won,
|
|
winner: result.winner&.to_s
|
|
)
|
|
rescue ArgumentError => e
|
|
render json: { error: e.message }, status: :unprocessable_entity
|
|
end
|
|
|
|
def pause
|
|
Sessions::Pause.new(@session).call
|
|
render json: status_payload
|
|
end
|
|
|
|
def stop
|
|
Sessions::Stop.new(@session).call
|
|
render json: status_payload
|
|
end
|
|
|
|
private
|
|
|
|
def set_session_from_token
|
|
@session = Sessions::RegiaAccess.find_session_by_token(params[:token])
|
|
return if @session
|
|
|
|
render file: Rails.root.join("public/404.html"), status: :not_found, layout: false
|
|
throw :abort
|
|
end
|
|
|
|
def status_payload
|
|
score = @session.score_state
|
|
closed = @session.terminal?
|
|
playable = !closed && mediamtx_stream_playable?(@session)
|
|
{
|
|
status: @session.status,
|
|
paused: @session.paused?,
|
|
stream_closed: closed,
|
|
live: !closed && (@session.live? || @session.paused? || mediamtx_publisher_online?(@session)),
|
|
on_air: playable,
|
|
publisher_online: !closed && mediamtx_publisher_online?(@session),
|
|
ended_at: @session.ended_at,
|
|
home_name: @session.match.team.name,
|
|
away_name: @session.match.opponent_name,
|
|
points_target: Scoring::Rules.from_match(@session.match).points_target(score&.current_set || 1),
|
|
score: score&.as_cable_payload
|
|
}
|
|
end
|
|
end
|
|
end
|