Rende usabili calendario, overlay ospite e stato diretta del cartellone.
Il calendario non deve più scorrere in orizzontale, il logo a destra non copre il nome e una diretta YouTube o in collegamento compare come In diretta. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,19 +38,21 @@ module Public
|
||||
.includes(
|
||||
:tournament_group,
|
||||
:tournament_round,
|
||||
:stream_sessions,
|
||||
home_participant: { logo_file_attachment: :blob },
|
||||
away_participant: { logo_file_attachment: :blob }
|
||||
)
|
||||
.order(Arel.sql("scheduled_at ASC NULLS LAST"), created_at: :asc)
|
||||
|
||||
@live_sessions = StreamSession
|
||||
broadcasting = StreamSession
|
||||
.broadcasting
|
||||
.publicly_listed
|
||||
.where(platform: "matchlivetv")
|
||||
.includes(:score_state, match: [:home_participant, :away_participant, { team: :club }])
|
||||
.where(match_id: @tournament.matches.select(:id))
|
||||
.order(Arel.sql("started_at DESC NULLS LAST"), created_at: :desc)
|
||||
@live_by_match_id = @live_sessions.index_by(&:match_id)
|
||||
.to_a
|
||||
@live_by_match_id = {}
|
||||
broadcasting.each { |session| @live_by_match_id[session.match_id] ||= session }
|
||||
@live_sessions = broadcasting.select(&:public_watchable?)
|
||||
|
||||
@recordings = Recording.ready.publicly_listed
|
||||
.joins(stream_session: :match)
|
||||
|
||||
@@ -67,7 +67,7 @@ module Public
|
||||
sessions = match.stream_sessions.to_a
|
||||
latest = sessions.max_by(&:created_at)
|
||||
if latest && !latest.status.in?(%w[ended error])
|
||||
return :live if latest.status.in?(%w[live reconnecting paused])
|
||||
return :live if latest.status.in?(%w[live reconnecting paused connecting])
|
||||
|
||||
return :waiting_operator
|
||||
end
|
||||
@@ -106,6 +106,18 @@ module Public
|
||||
:waiting
|
||||
end
|
||||
|
||||
def tournament_public_watch_target(session)
|
||||
return unless session
|
||||
if session.matchlivetv_platform? && session.publicly_listed?
|
||||
return [public_live_path(session), t("tournaments.page.watch_live"), {}]
|
||||
end
|
||||
if session.youtube_watch_url.present?
|
||||
return [session.youtube_watch_url, t("live.show.youtube_watch_link"), { target: "_blank", rel: "noopener" }]
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def tournament_public_score_label(match)
|
||||
return "#{match.home_score}–#{match.away_score}" if match.home_score.present? && match.away_score.present?
|
||||
|
||||
|
||||
@@ -186,6 +186,12 @@ class StreamSession < ApplicationRecord
|
||||
platform == "youtube" && youtube_watch_url.present?
|
||||
end
|
||||
|
||||
def public_watchable?
|
||||
return true if matchlivetv_platform? && publicly_listed?
|
||||
|
||||
youtube_ready?
|
||||
end
|
||||
|
||||
def link_only?
|
||||
privacy_status.in?(%w[unlisted private])
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<%= render "shared/analytics_suppress" %>
|
||||
<%= yield :head %>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer">
|
||||
<link rel="stylesheet" href="/marketing.css?v=101">
|
||||
<link rel="stylesheet" href="/marketing.css?v=102">
|
||||
</head>
|
||||
<body data-confirm-i18n='<%= raw confirm_dialog_i18n_json %>'<% if MatchLiveTv.google_analytics_configured? %> data-ga-id="<%= MatchLiveTv.google_analytics_measurement_id %>"<% end %>>
|
||||
<%= render "shared/cookie_banner" %>
|
||||
@@ -24,7 +24,7 @@
|
||||
<%= render(@app_store_review_chrome ? "shared/marketing_footer_app_store" : "shared/marketing_footer") %>
|
||||
<script src="/branding-form.js?v=1" defer></script>
|
||||
<script src="/tournament-invite-editor.js?v=2" defer></script>
|
||||
<script src="/tournament-calendar.js?v=1" defer></script>
|
||||
<script src="/tournament-calendar.js?v=2" defer></script>
|
||||
<script src="/roster-form.js?v=1" defer></script>
|
||||
<script src="/password-toggle.js?v=2" defer></script>
|
||||
<link rel="stylesheet" href="/confirm-forms.css?v=4">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<%= render "shared/meta_tags" %>
|
||||
<%= render "shared/analytics_suppress" %>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer">
|
||||
<link rel="stylesheet" href="/marketing.css?v=101">
|
||||
<link rel="stylesheet" href="/marketing.css?v=102">
|
||||
<link rel="stylesheet" href="/live.css?v=26">
|
||||
<%= yield :head %>
|
||||
</head>
|
||||
|
||||
@@ -37,8 +37,12 @@
|
||||
</span>
|
||||
</td>
|
||||
<td class="tournament-board__actions">
|
||||
<% if live_session %>
|
||||
<%= link_to t("tournaments.page.watch_live"), public_live_path(live_session), class: "tournament-board__cta tournament-board__cta--live" %>
|
||||
<% watch = tournament_public_watch_target(live_session) %>
|
||||
<% if watch %>
|
||||
<% url, label, html_opts = watch %>
|
||||
<%= link_to label, url, { class: "tournament-board__cta tournament-board__cta--live" }.merge(html_opts) %>
|
||||
<% elsif live_session %>
|
||||
<span class="muted"><%= t("tournaments.page.no_media") %></span>
|
||||
<% elsif recording %>
|
||||
<%= link_to t("tournaments.page.watch_replay"), public_replay_path(recording.stream_session_id), class: "tournament-board__cta" %>
|
||||
<% else %>
|
||||
|
||||
@@ -64,7 +64,11 @@
|
||||
<span class="badge badge-live"><%= t("live.index.badge_live") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= link_to t("tournaments.page.watch_live"), public_live_path(session), class: "btn-watch" %>
|
||||
<% watch = tournament_public_watch_target(session) %>
|
||||
<% if watch %>
|
||||
<% url, label, html_opts = watch %>
|
||||
<%= link_to label, url, { class: "btn-watch" }.merge(html_opts) %>
|
||||
<% end %>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -8,88 +8,105 @@
|
||||
|
||||
<% if @matches.any? %>
|
||||
<p class="tournament-hub-hint" style="margin-top:16px"><%= t("tournaments.hub.calendar_edit_hint") %></p>
|
||||
<div class="tournament-table-wrap">
|
||||
<table class="data tournament-match-table" data-swap-error="<%= t("flash.tournaments.sides_swap_failed") %>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("tournaments.hub.datetime") %></th>
|
||||
<th><%= t("tournaments.hub.court") %></th>
|
||||
<th><%= t("tournaments.hub.round") %></th>
|
||||
<th><%= t("tournaments.hub.home") %></th>
|
||||
<th class="tournament-match-swap-col"></th>
|
||||
<th><%= t("tournaments.hub.away") %></th>
|
||||
<th><%= t("tournaments.hub.result") %></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @matches.each do |match| %>
|
||||
<% form_id = "match-edit-#{match.id}" %>
|
||||
<% courts = (@tournament.court_list + [match.court]).compact_blank.uniq %>
|
||||
<%= form_with url: public_tournament_match_path(@tournament, match), method: :patch, html: { id: form_id, class: "visually-hidden" } do %>
|
||||
<%= hidden_field_tag :tab, @tab, form: form_id %>
|
||||
<% end %>
|
||||
<tr>
|
||||
<% if @writable %>
|
||||
<td>
|
||||
<%= datetime_local_field_tag "match[scheduled_at]", tournament_datetime_local(match.scheduled_at),
|
||||
id: "match_at_#{match.id}", form: form_id, required: true, class: "tournament-match-form__datetime" %>
|
||||
</td>
|
||||
<td>
|
||||
<%= select_tag "match[court]", options_for_select(courts, match.court),
|
||||
id: "match_court_#{match.id}", form: form_id, include_blank: true, class: "tournament-match-form__court" %>
|
||||
</td>
|
||||
<td><%= tournament_phase_label(match) %></td>
|
||||
<td data-swap-side="home"><%= render "public/tournaments/match_side_select", match: match, side: :home, form_id: form_id %></td>
|
||||
<td class="tournament-match-swap-col">
|
||||
<%= button_to public_swap_tournament_match_path(@tournament, match), method: :post,
|
||||
class: "tournament-match-swap__btn",
|
||||
title: t("tournaments.hub.swap_sides"),
|
||||
form: { class: "tournament-match-swap__form", data: { turbo: false } } do %>
|
||||
<i class="fa-solid fa-right-left" aria-hidden="true"></i>
|
||||
<span class="visually-hidden"><%= t("tournaments.hub.swap_sides") %></span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td data-swap-side="away"><%= render "public/tournaments/match_side_select", match: match, side: :away, form_id: form_id %></td>
|
||||
<td>
|
||||
<% if match.played? || match.result_status.to_s.start_with?("walkover") %>
|
||||
<span data-swap-played-score><%= match.home_score %>–<%= match.away_score %></span>
|
||||
<% else %>
|
||||
<span class="tournament-match-form__score">
|
||||
<%= number_field_tag :home_score, match.home_score, id: "home_score_#{match.id}", form: form_id, data: { swap_score: "home" } %>
|
||||
<span>–</span>
|
||||
<%= number_field_tag :away_score, match.away_score, id: "away_score_#{match.id}", form: form_id, data: { swap_score: "away" } %>
|
||||
</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="tournament-match-form__actions">
|
||||
<%= submit_tag t("tournaments.hub.save_match"), form: form_id, class: "btn btn-secondary tournament-match-form__save" %>
|
||||
<% if match.deletable? %>
|
||||
<%= button_to t("matches.index.delete"), public_tournament_match_path(@tournament, match),
|
||||
method: :delete, class: "btn btn-secondary tournament-match-form__save",
|
||||
form: { class: "tournament-match-delete-form", data: { turbo_confirm: match.matchup_label } } %>
|
||||
<% end %>
|
||||
</td>
|
||||
<% else %>
|
||||
<td><%= match.scheduled_at ? l(match.scheduled_at, format: :short) : "—" %></td>
|
||||
<td><%= match.court || "—" %></td>
|
||||
<td><%= tournament_phase_label(match) %></td>
|
||||
<td><%= tournament_team_chip(match.home_participant, name: match.home_display_name) %></td>
|
||||
<td class="tournament-match-swap-col"></td>
|
||||
<td><%= tournament_team_chip(match.away_participant, name: match.away_display_name) %></td>
|
||||
<td>
|
||||
<div class="tournament-match-list tournament-match-table" data-swap-error="<%= t("flash.tournaments.sides_swap_failed") %>">
|
||||
<% @matches.each do |match| %>
|
||||
<% form_id = "match-edit-#{match.id}" %>
|
||||
<% courts = (@tournament.court_list + [match.court]).compact_blank.uniq %>
|
||||
<%= form_with url: public_tournament_match_path(@tournament, match), method: :patch, html: { id: form_id, class: "visually-hidden" } do %>
|
||||
<%= hidden_field_tag :tab, @tab, form: form_id %>
|
||||
<% end %>
|
||||
<article class="tournament-match-row">
|
||||
<% if @writable %>
|
||||
<div class="tournament-match-row__field">
|
||||
<label for="match_at_<%= match.id %>"><%= t("tournaments.hub.datetime") %></label>
|
||||
<%= datetime_local_field_tag "match[scheduled_at]", tournament_datetime_local(match.scheduled_at),
|
||||
id: "match_at_#{match.id}", form: form_id, required: true, class: "tournament-match-form__datetime" %>
|
||||
</div>
|
||||
<div class="tournament-match-row__field">
|
||||
<label for="match_court_<%= match.id %>"><%= t("tournaments.hub.court") %></label>
|
||||
<%= select_tag "match[court]", options_for_select(courts, match.court),
|
||||
id: "match_court_#{match.id}", form: form_id, include_blank: true, class: "tournament-match-form__court" %>
|
||||
</div>
|
||||
<div class="tournament-match-row__field tournament-match-row__field--phase">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.round") %></span>
|
||||
<p class="tournament-match-row__phase"><%= tournament_phase_label(match) %></p>
|
||||
</div>
|
||||
<div class="tournament-match-row__sides">
|
||||
<div class="tournament-match-row__side">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.home") %></span>
|
||||
<div data-swap-side="home"><%= render "public/tournaments/match_side_select", match: match, side: :home, form_id: form_id %></div>
|
||||
</div>
|
||||
<div class="tournament-match-swap-col">
|
||||
<%= button_to public_swap_tournament_match_path(@tournament, match), method: :post,
|
||||
class: "tournament-match-swap__btn",
|
||||
title: t("tournaments.hub.swap_sides"),
|
||||
form: { class: "tournament-match-swap__form", data: { turbo: false } } do %>
|
||||
<i class="fa-solid fa-right-left" aria-hidden="true"></i>
|
||||
<span class="visually-hidden"><%= t("tournaments.hub.swap_sides") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="tournament-match-row__side">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.away") %></span>
|
||||
<div data-swap-side="away"><%= render "public/tournaments/match_side_select", match: match, side: :away, form_id: form_id %></div>
|
||||
</div>
|
||||
<div class="tournament-match-row__score">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.result") %></span>
|
||||
<% if match.played? || match.result_status.to_s.start_with?("walkover") %>
|
||||
<p data-swap-played-score><%= match.home_score %>–<%= match.away_score %></p>
|
||||
<% else %>
|
||||
<span class="tournament-match-form__score">
|
||||
<%= number_field_tag :home_score, match.home_score, id: "home_score_#{match.id}", form: form_id, data: { swap_score: "home" } %>
|
||||
<span>–</span>
|
||||
<%= number_field_tag :away_score, match.away_score, id: "away_score_#{match.id}", form: form_id, data: { swap_score: "away" } %>
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tournament-match-form__actions tournament-match-row__actions">
|
||||
<%= submit_tag t("tournaments.hub.save_match"), form: form_id, class: "btn btn-secondary tournament-match-form__save" %>
|
||||
<% if match.deletable? %>
|
||||
<%= button_to t("matches.index.delete"), public_tournament_match_path(@tournament, match),
|
||||
method: :delete, class: "btn btn-secondary tournament-match-form__save",
|
||||
form: { class: "tournament-match-delete-form", data: { turbo_confirm: match.matchup_label } } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="tournament-match-row__field">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.datetime") %></span>
|
||||
<p class="tournament-match-row__phase"><%= match.scheduled_at ? l(match.scheduled_at, format: :short) : "—" %></p>
|
||||
</div>
|
||||
<div class="tournament-match-row__field">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.court") %></span>
|
||||
<p class="tournament-match-row__phase"><%= match.court || "—" %></p>
|
||||
</div>
|
||||
<div class="tournament-match-row__field tournament-match-row__field--phase">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.round") %></span>
|
||||
<p class="tournament-match-row__phase"><%= tournament_phase_label(match) %></p>
|
||||
</div>
|
||||
<div class="tournament-match-row__sides">
|
||||
<div class="tournament-match-row__side">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.home") %></span>
|
||||
<%= tournament_team_chip(match.home_participant, name: match.home_display_name) %>
|
||||
</div>
|
||||
<div class="tournament-match-swap-col" aria-hidden="true"></div>
|
||||
<div class="tournament-match-row__side">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.away") %></span>
|
||||
<%= tournament_team_chip(match.away_participant, name: match.away_display_name) %>
|
||||
</div>
|
||||
<div class="tournament-match-row__score">
|
||||
<span class="tournament-match-row__label"><%= t("tournaments.hub.result") %></span>
|
||||
<p>
|
||||
<% if match.home_score.present? %>
|
||||
<%= match.home_score %>–<%= match.away_score %>
|
||||
<% else %>
|
||||
—
|
||||
<% end %>
|
||||
</td>
|
||||
<td></td>
|
||||
<% end %>
|
||||
</tr>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p class="tournament-hub-hint" style="margin-top:16px"><%= t("tournaments.hub.no_matches") %></p>
|
||||
|
||||
Reference in New Issue
Block a user