Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45bdda7c95 | ||
|
|
b926531447 | ||
|
|
da6fc1d523 | ||
|
|
1d1cbf9f3f | ||
|
|
dd9901519a | ||
|
|
53449c5d3c | ||
|
|
db908e3109 | ||
|
|
5857f60d79 |
@@ -9,13 +9,23 @@ module Admin
|
|||||||
return render :edit, status: :unprocessable_entity
|
return render :edit, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:password].blank? || params[:password].length < 8
|
if params[:password] != params[:password_confirmation]
|
||||||
flash.now[:alert] = t("admin.flash.password_too_short")
|
flash.now[:alert] = t("admin.flash.password_mismatch")
|
||||||
return render :edit, status: :unprocessable_entity
|
return render :edit, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:password] != params[:password_confirmation]
|
if (code = PasswordComplexity.violation(params[:password]))
|
||||||
flash.now[:alert] = t("admin.flash.password_mismatch")
|
key = case code
|
||||||
|
when :blank, :too_short then :password_too_short
|
||||||
|
when :too_long then :password_too_long
|
||||||
|
else :password_too_weak
|
||||||
|
end
|
||||||
|
flash.now[:alert] = t("admin.flash.#{key}")
|
||||||
|
return render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
if PasswordComplexity.same_as_current?(current_admin_account, params[:password])
|
||||||
|
flash.now[:alert] = t("admin.flash.password_same_as_current")
|
||||||
return render :edit, status: :unprocessable_entity
|
return render :edit, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ module Api
|
|||||||
def update
|
def update
|
||||||
name = params[:name].to_s.strip
|
name = params[:name].to_s.strip
|
||||||
if name.blank?
|
if name.blank?
|
||||||
return render json: { error: "Name is required" }, status: :unprocessable_entity
|
return render json: { error: I18n.t("flash.accounts.name_required") }, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
if current_user.update(name: name)
|
if current_user.update(name: name)
|
||||||
@@ -30,7 +30,7 @@ module Api
|
|||||||
return render json: { error: password_error_message(result.error) }, status: :unprocessable_entity
|
return render json: { error: password_error_message(result.error) }, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: { message: "Password updated" }
|
render json: { message: I18n.t("flash.accounts.password_updated") }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -46,10 +46,13 @@ module Api
|
|||||||
|
|
||||||
def password_error_message(code)
|
def password_error_message(code)
|
||||||
case code
|
case code
|
||||||
when :current_incorrect then "Current password is incorrect"
|
when :current_incorrect then I18n.t("flash.accounts.password_current_incorrect")
|
||||||
when :too_short then "Password must be at least 8 characters"
|
when :too_short then I18n.t("flash.accounts.password_too_short")
|
||||||
when :mismatch then "Passwords do not match"
|
when :too_long then I18n.t("flash.accounts.password_too_long")
|
||||||
else "Unable to update password"
|
when :too_weak then I18n.t("flash.accounts.password_too_weak")
|
||||||
|
when :same_as_current then I18n.t("flash.accounts.password_same_as_current")
|
||||||
|
when :mismatch then I18n.t("flash.accounts.password_mismatch")
|
||||||
|
else I18n.t("flash.accounts.password_update_failed")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,18 +22,18 @@ module Api
|
|||||||
if user&.authenticate(params[:password])
|
if user&.authenticate(params[:password])
|
||||||
render json: token_response(user), status: :ok
|
render json: token_response(user), status: :ok
|
||||||
else
|
else
|
||||||
render json: { error: "Invalid credentials" }, status: :unauthorized
|
render json: { error: I18n.t("flash.sessions.invalid_credentials") }, status: :unauthorized
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def logout
|
def logout
|
||||||
render json: { message: "Logged out" }
|
render json: { message: I18n.t("flash.sessions.logged_out") }
|
||||||
end
|
end
|
||||||
|
|
||||||
def refresh
|
def refresh
|
||||||
payload = JsonWebToken.decode(params[:refresh_token] || bearer_token)
|
payload = JsonWebToken.decode(params[:refresh_token] || bearer_token)
|
||||||
user = User.find_by(id: payload&.dig(:user_id))
|
user = User.find_by(id: payload&.dig(:user_id))
|
||||||
return render json: { error: "Invalid token" }, status: :unauthorized unless user
|
return render json: { error: I18n.t("flash.sessions.invalid_token") }, status: :unauthorized unless user
|
||||||
|
|
||||||
render json: token_response(user)
|
render json: token_response(user)
|
||||||
end
|
end
|
||||||
@@ -45,7 +45,7 @@ module Api
|
|||||||
def forgot_password
|
def forgot_password
|
||||||
Users::RequestPasswordReset.call(email: params[:email])
|
Users::RequestPasswordReset.call(email: params[:email])
|
||||||
render json: {
|
render json: {
|
||||||
message: "If the email is registered, you will receive a password reset link shortly."
|
message: I18n.t("flash.password_resets.email_sent")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,25 @@
|
|||||||
class ApplicationController < ActionController::API
|
class ApplicationController < ActionController::API
|
||||||
include ActionController::HttpAuthentication::Token::ControllerMethods
|
include ActionController::HttpAuthentication::Token::ControllerMethods
|
||||||
|
|
||||||
|
before_action :set_api_locale
|
||||||
before_action :authenticate_request!
|
before_action :authenticate_request!
|
||||||
|
|
||||||
attr_reader :current_user
|
attr_reader :current_user
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_api_locale
|
||||||
|
explicit = LocaleResolver.normalize(request.headers["X-Locale"])
|
||||||
|
I18n.locale = explicit ||
|
||||||
|
LocaleResolver.from_accept_language(request.headers["Accept-Language"]) ||
|
||||||
|
I18n.default_locale
|
||||||
|
end
|
||||||
|
|
||||||
def authenticate_request!
|
def authenticate_request!
|
||||||
token = bearer_token
|
token = bearer_token
|
||||||
payload = JsonWebToken.decode(token)
|
payload = JsonWebToken.decode(token)
|
||||||
@current_user = User.find_by(id: payload[:user_id]) if payload
|
@current_user = User.find_by(id: payload[:user_id]) if payload
|
||||||
render json: { error: "Unauthorized" }, status: :unauthorized unless @current_user
|
render json: { error: I18n.t("flash.sessions.unauthorized") }, status: :unauthorized unless @current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def bearer_token
|
def bearer_token
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ module Public
|
|||||||
)
|
)
|
||||||
|
|
||||||
unless result.ok?
|
unless result.ok?
|
||||||
flash.now[:alert] = t("flash.accounts.password_#{result.error}")
|
redirect_to public_account_path, alert: t("flash.accounts.password_#{result.error}")
|
||||||
return render :show, status: :unprocessable_entity
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to public_account_path, notice: t("flash.accounts.password_updated")
|
redirect_to public_account_path, notice: t("flash.accounts.password_updated")
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module Public
|
|||||||
def edit
|
def edit
|
||||||
@user = User.find_by_password_reset_token(params[:token])
|
@user = User.find_by_password_reset_token(params[:token])
|
||||||
if @user.nil? || @user.password_reset_expired?
|
if @user.nil? || @user.password_reset_expired?
|
||||||
redirect_to new_public_password_reset_path,
|
redirect_to public_password_forgot_path,
|
||||||
alert: t("flash.password_resets.invalid_or_expired_link")
|
alert: t("flash.password_resets.invalid_or_expired_link")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -23,19 +23,25 @@ module Public
|
|||||||
def update
|
def update
|
||||||
@user = User.find_by_password_reset_token(params[:token])
|
@user = User.find_by_password_reset_token(params[:token])
|
||||||
if @user.nil? || @user.password_reset_expired?
|
if @user.nil? || @user.password_reset_expired?
|
||||||
redirect_to new_public_password_reset_path,
|
redirect_to public_password_forgot_path,
|
||||||
alert: t("flash.password_resets.invalid_or_expired_link")
|
alert: t("flash.password_resets.invalid_or_expired_link")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:password].blank? || params[:password].length < 8
|
if params[:password] != params[:password_confirmation]
|
||||||
flash.now[:alert] = t("flash.password_resets.password_min_length")
|
flash.now[:alert] = t("flash.password_resets.password_mismatch")
|
||||||
@token = params[:token]
|
@token = params[:token]
|
||||||
return render :edit, status: :unprocessable_entity
|
return render :edit, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:password] != params[:password_confirmation]
|
if (code = PasswordComplexity.violation(params[:password]))
|
||||||
flash.now[:alert] = t("flash.password_resets.password_mismatch")
|
flash.now[:alert] = t("flash.password_resets.password_#{code == :blank ? :too_short : code}")
|
||||||
|
@token = params[:token]
|
||||||
|
return render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
if PasswordComplexity.same_as_current?(@user, params[:password])
|
||||||
|
flash.now[:alert] = t("flash.password_resets.password_same_as_current")
|
||||||
@token = params[:token]
|
@token = params[:token]
|
||||||
return render :edit, status: :unprocessable_entity
|
return render :edit, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
class AdminAccount < ApplicationRecord
|
class AdminAccount < ApplicationRecord
|
||||||
|
include PasswordComplexity
|
||||||
|
|
||||||
has_secure_password
|
has_secure_password
|
||||||
|
|
||||||
validates :username, presence: true, uniqueness: true
|
validates :username, presence: true, uniqueness: true
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Criteri "di mercato" (stile Cognito/Auth0 bilanciato):
|
||||||
|
# - minimo 8 caratteri (max 72 per bcrypt)
|
||||||
|
# - almeno 3 classi su 4: minuscole, maiuscole, numeri, simboli
|
||||||
|
module PasswordComplexity
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
MIN_LENGTH = 8
|
||||||
|
MAX_LENGTH = 72
|
||||||
|
REQUIRED_CLASSES = 3
|
||||||
|
|
||||||
|
CLASS_CHECKS = {
|
||||||
|
lowercase: /[a-z]/,
|
||||||
|
uppercase: /[A-Z]/,
|
||||||
|
digit: /\d/,
|
||||||
|
symbol: /[^A-Za-z0-9]/
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def violation(password)
|
||||||
|
value = password.to_s
|
||||||
|
return :blank if value.blank?
|
||||||
|
return :too_short if value.length < MIN_LENGTH
|
||||||
|
return :too_long if value.bytesize > MAX_LENGTH
|
||||||
|
return :too_weak unless strong_enough?(value)
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def strong_enough?(password)
|
||||||
|
matched = CLASS_CHECKS.count { |_, pattern| password.match?(pattern) }
|
||||||
|
matched >= REQUIRED_CLASSES
|
||||||
|
end
|
||||||
|
|
||||||
|
# Confronta con il digest già salvato (prima di assegnare la nuova password).
|
||||||
|
def same_as_current?(record, password)
|
||||||
|
return false if password.blank? || !record.respond_to?(:authenticate)
|
||||||
|
|
||||||
|
record.authenticate(password).present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def requirement_summary
|
||||||
|
I18n.t("password_policy.hint")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
included do
|
||||||
|
validate :password_meets_complexity_policy, if: -> { password.present? }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def password_meets_complexity_policy
|
||||||
|
case PasswordComplexity.violation(password)
|
||||||
|
when :too_short
|
||||||
|
errors.add(:password, :too_short, count: MIN_LENGTH)
|
||||||
|
when :too_long
|
||||||
|
errors.add(:password, :too_long, count: MAX_LENGTH)
|
||||||
|
when :too_weak
|
||||||
|
errors.add(:password, :complexity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
|
include PasswordComplexity
|
||||||
|
|
||||||
ROLES = %w[admin coach parent volunteer].freeze
|
ROLES = %w[admin coach parent volunteer].freeze
|
||||||
|
|
||||||
has_secure_password
|
has_secure_password
|
||||||
|
|||||||
@@ -23,15 +23,23 @@ module Users
|
|||||||
return Result.new(ok?: false, error: :current_incorrect)
|
return Result.new(ok?: false, error: :current_incorrect)
|
||||||
end
|
end
|
||||||
|
|
||||||
if @password.blank? || @password.length < 8
|
|
||||||
return Result.new(ok?: false, error: :too_short)
|
|
||||||
end
|
|
||||||
|
|
||||||
if @password != @password_confirmation
|
if @password != @password_confirmation
|
||||||
return Result.new(ok?: false, error: :mismatch)
|
return Result.new(ok?: false, error: :mismatch)
|
||||||
end
|
end
|
||||||
|
|
||||||
@user.update!(password: @password)
|
if (code = PasswordComplexity.violation(@password))
|
||||||
|
return Result.new(ok?: false, error: code == :blank ? :too_short : code)
|
||||||
|
end
|
||||||
|
|
||||||
|
if PasswordComplexity.same_as_current?(@user, @password)
|
||||||
|
return Result.new(ok?: false, error: :same_as_current)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless @user.update(password: @password)
|
||||||
|
complexity_error = @user.errors.details[:password]&.any? { |d| d[:error] == :complexity }
|
||||||
|
return Result.new(ok?: false, error: complexity_error ? :too_weak : :too_short)
|
||||||
|
end
|
||||||
|
|
||||||
@user.clear_password_reset!
|
@user.clear_password_reset!
|
||||||
Result.new(ok?: true)
|
Result.new(ok?: true)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<%= render "shared/meta_tags" %>
|
<%= render "shared/meta_tags" %>
|
||||||
<%= yield :head %>
|
<%= 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="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=44">
|
<link rel="stylesheet" href="/marketing.css?v=50">
|
||||||
</head>
|
</head>
|
||||||
<body data-confirm-i18n='<%= raw confirm_dialog_i18n_json %>'<% if MatchLiveTv.google_analytics_configured? %> data-ga-id="<%= MatchLiveTv.google_analytics_measurement_id %>"<% end %>>
|
<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" %>
|
<%= render "shared/cookie_banner" %>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<title><%= content_for?(:title) ? yield(:title) : "Match Live TV" %></title>
|
<title><%= content_for?(:title) ? yield(:title) : "Match Live TV" %></title>
|
||||||
<%= render "shared/meta_tags" %>
|
<%= render "shared/meta_tags" %>
|
||||||
<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="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=44">
|
<link rel="stylesheet" href="/marketing.css?v=50">
|
||||||
<link rel="stylesheet" href="/live.css?v=26">
|
<link rel="stylesheet" href="/live.css?v=26">
|
||||||
<%= yield :head %>
|
<%= yield :head %>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2 style="font-size:1.1rem;margin-top:0"><%= t("auth.account.password_heading") %></h2>
|
<h2 style="font-size:1.1rem;margin-top:0"><%= t("auth.account.password_heading") %></h2>
|
||||||
|
<p class="muted" style="font-size:0.9rem"><%= t("password_policy.hint") %></p>
|
||||||
<%= form_with url: public_account_password_path, method: :patch, local: true do %>
|
<%= form_with url: public_account_password_path, method: :patch, local: true do %>
|
||||||
<%= render "shared/input_toggle",
|
<%= render "shared/input_toggle",
|
||||||
name: :current_password,
|
name: :current_password,
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<% content_for :meta_description, t("auth.invitation.meta_description") %>
|
<% content_for :meta_description, t("auth.invitation.meta_description") %>
|
||||||
<% content_for :robots, "noindex, nofollow" %>
|
<% content_for :robots, "noindex, nofollow" %>
|
||||||
|
|
||||||
<div class="card" style="max-width:480px">
|
<section class="auth-page">
|
||||||
|
<div class="card">
|
||||||
<h1><%= raw t("auth.invitation.title_html", team_name: @invitation.team.name) %></h1>
|
<h1><%= raw t("auth.invitation.title_html", team_name: @invitation.team.name) %></h1>
|
||||||
<p><%= raw t("auth.invitation.role_notice_html", email: @invitation.email) %></p>
|
<p><%= raw t("auth.invitation.role_notice_html", email: @invitation.email) %></p>
|
||||||
<p class="muted" style="font-size:0.9rem;margin-bottom:16px">
|
<p class="muted" style="font-size:0.9rem;margin-bottom:16px">
|
||||||
@@ -24,3 +25,4 @@
|
|||||||
<a href="matchlivetv://join/<%= @token %>"><%= t("auth.invitation.open_in_app") %></a>
|
<a href="matchlivetv://join/<%= @token %>"><%= t("auth.invitation.open_in_app") %></a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
<h3><%= t("legal.cookies.s4_1_title") %></h3>
|
<h3><%= t("legal.cookies.s4_1_title") %></h3>
|
||||||
<p><%= t("legal.cookies.s4_1_intro") %></p>
|
<p><%= t("legal.cookies.s4_1_intro") %></p>
|
||||||
|
<div class="table-scroll">
|
||||||
<table class="legal-table">
|
<table class="legal-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th><%= t("legal.cookies.table_col_name") %></th><th><%= t("legal.cookies.table_col_purpose") %></th><th><%= t("legal.cookies.table_col_duration") %></th><th><%= t("legal.cookies.table_col_provider") %></th></tr>
|
<tr><th><%= t("legal.cookies.table_col_name") %></th><th><%= t("legal.cookies.table_col_purpose") %></th><th><%= t("legal.cookies.table_col_duration") %></th><th><%= t("legal.cookies.table_col_provider") %></th></tr>
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3><%= t("legal.cookies.s4_2_title") %></h3>
|
<h3><%= t("legal.cookies.s4_2_title") %></h3>
|
||||||
<p>
|
<p>
|
||||||
@@ -75,6 +77,7 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<p class="muted"><%= t("legal.cookies.s4_2_inactive") %></p>
|
<p class="muted"><%= t("legal.cookies.s4_2_inactive") %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<div class="table-scroll">
|
||||||
<table class="legal-table">
|
<table class="legal-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th><%= t("legal.cookies.table2_col_name") %></th><th><%= t("legal.cookies.table_col_purpose") %></th><th><%= t("legal.cookies.table_col_duration") %></th><th><%= t("legal.cookies.table_col_provider") %></th></tr>
|
<tr><th><%= t("legal.cookies.table2_col_name") %></th><th><%= t("legal.cookies.table_col_purpose") %></th><th><%= t("legal.cookies.table_col_duration") %></th><th><%= t("legal.cookies.table_col_provider") %></th></tr>
|
||||||
@@ -100,6 +103,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<%= raw t(
|
<%= raw t(
|
||||||
"legal.cookies.s4_2_p2_html",
|
"legal.cookies.s4_2_p2_html",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
<%= render "shared/plan_cards" %>
|
<%= render "shared/plan_cards" %>
|
||||||
|
|
||||||
|
<div class="table-scroll">
|
||||||
<table class="compare-table">
|
<table class="compare-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th></th><th>Free</th><th>Premium Light</th><th>Premium Full</th></tr>
|
<tr><th></th><th>Free</th><th>Premium Light</th><th>Premium Full</th></tr>
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
<tr><td><%= t("pages.pricing.table_price") %></td><td><%= t("pages.pricing.table_price_free") %></td><td><%= raw t("pages.pricing.table_price_light_html") %></td><td><%= raw t("pages.pricing.table_price_full_html") %></td></tr>
|
<tr><td><%= t("pages.pricing.table_price") %></td><td><%= t("pages.pricing.table_price_free") %></td><td><%= raw t("pages.pricing.table_price_light_html") %></td><td><%= raw t("pages.pricing.table_price_full_html") %></td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card" style="margin-top:32px;text-align:center">
|
<div class="card" style="margin-top:32px;text-align:center">
|
||||||
<h3 style="margin-top:0"><%= t("pages.pricing.different_title") %></h3>
|
<h3 style="margin-top:0"><%= t("pages.pricing.different_title") %></h3>
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2><%= t("legal.privacy.s5_title") %></h2>
|
<h2><%= t("legal.privacy.s5_title") %></h2>
|
||||||
|
<div class="table-scroll">
|
||||||
<table class="legal-table">
|
<table class="legal-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th><%= t("legal.privacy.s5_col_purpose") %></th><th><%= t("legal.privacy.s5_col_basis") %></th></tr>
|
<tr><th><%= t("legal.privacy.s5_col_purpose") %></th><th><%= t("legal.privacy.s5_col_basis") %></th></tr>
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<section class="auth-page">
|
<section class="auth-page">
|
||||||
<h1><%= t("auth.password_reset.title") %></h1>
|
<h1><%= t("auth.password_reset.title") %></h1>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<p class="muted" style="font-size:0.9rem"><%= t("password_policy.hint") %></p>
|
||||||
<%= form_with url: public_password_reset_path, method: :patch, local: true do %>
|
<%= form_with url: public_password_reset_path, method: :patch, local: true do %>
|
||||||
<%= hidden_field_tag :token, @token %>
|
<%= hidden_field_tag :token, @token %>
|
||||||
<%= render "shared/input_toggle",
|
<%= render "shared/input_toggle",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
required: true,
|
required: true,
|
||||||
minlength: 8,
|
minlength: 8,
|
||||||
autocomplete: "new-password" %>
|
autocomplete: "new-password" %>
|
||||||
|
<p class="muted" style="font-size:0.9rem;margin-top:-0.5rem"><%= t("password_policy.hint") %></p>
|
||||||
<%= render "shared/input_toggle",
|
<%= render "shared/input_toggle",
|
||||||
name: "user[password_confirmation]",
|
name: "user[password_confirmation]",
|
||||||
id: "user_password_confirmation",
|
id: "user_password_confirmation",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
<h3 style="margin-top:28px;font-size:1.1rem"><%= t("billing.documents.table_heading") %></h3>
|
<h3 style="margin-top:28px;font-size:1.1rem"><%= t("billing.documents.table_heading") %></h3>
|
||||||
<% if payments.any? %>
|
<% if payments.any? %>
|
||||||
|
<div class="table-scroll">
|
||||||
<table class="data billing-table">
|
<table class="data billing-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<p style="color:#888"><%= t("billing.documents.no_payments") %></p>
|
<p style="color:#888"><%= t("billing.documents.no_payments") %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -58,10 +58,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggle.addEventListener("click", function (e) {
|
toggle.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setOpen(menu.hidden);
|
setOpen(menu.hidden);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Keep parent mobile nav open while interacting with the switcher UI.
|
||||||
|
root.addEventListener("click", function (e) {
|
||||||
|
if (e.target.closest(".lang-switcher__toggle")) {
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener("click", function (e) {
|
document.addEventListener("click", function (e) {
|
||||||
if (!root.contains(e.target)) setOpen(false);
|
if (!root.contains(e.target)) setOpen(false);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,15 @@
|
|||||||
|
|
||||||
<nav id="site-nav" class="nav" aria-label="<%= t('nav.main_menu') %>" aria-hidden="true">
|
<nav id="site-nav" class="nav" aria-label="<%= t('nav.main_menu') %>" aria-hidden="true">
|
||||||
<div class="nav-panel">
|
<div class="nav-panel">
|
||||||
|
<div class="nav-mobile-head">
|
||||||
|
<%= link_to root_path, class: "nav-mobile-brand", aria: { label: "Match Live TV" }, title: "Match Live TV" do %>
|
||||||
|
<img class="nav-mobile-brand-logo" src="/logo.png?v=3" alt="" width="40" height="40" decoding="async">
|
||||||
|
<span class="brand">Match <span>Live TV</span></span>
|
||||||
|
<% end %>
|
||||||
|
<div class="nav-lang">
|
||||||
|
<%= render "shared/language_switcher" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<%= link_to t("nav.home"), root_path, class: (request.path == "/" ? "nav-active" : nil) %>
|
<%= link_to t("nav.home"), root_path, class: (request.path == "/" ? "nav-active" : nil) %>
|
||||||
<%= link_to t("nav.features"), public_features_path, class: (request.path == "/funzionalita" ? "nav-active" : nil) %>
|
<%= link_to t("nav.features"), public_features_path, class: (request.path == "/funzionalita" ? "nav-active" : nil) %>
|
||||||
<%= link_to t("nav.pricing"), public_prezzi_path, class: (request.path == "/prezzi" ? "nav-active" : nil) %>
|
<%= link_to t("nav.pricing"), public_prezzi_path, class: (request.path == "/prezzi" ? "nav-active" : nil) %>
|
||||||
@@ -40,9 +49,6 @@
|
|||||||
<%= link_to t("nav.login"), public_login_path, class: "nav-link-item" %>
|
<%= link_to t("nav.login"), public_login_path, class: "nav-link-item" %>
|
||||||
<%= link_to t("nav.signup"), public_signup_path, class: "btn btn-primary nav-btn" %>
|
<%= link_to t("nav.signup"), public_signup_path, class: "btn btn-primary nav-btn" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="nav-lang">
|
|
||||||
<%= render "shared/language_switcher" %>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -78,8 +84,16 @@
|
|||||||
|
|
||||||
if (backdrop) backdrop.addEventListener("click", closeMenu);
|
if (backdrop) backdrop.addEventListener("click", closeMenu);
|
||||||
|
|
||||||
|
function shouldCloseNavOnControl(el) {
|
||||||
|
// Language toggle must keep the mobile menu open; only a locale choice may close it.
|
||||||
|
if (!el.closest("[data-lang-switcher]")) return true;
|
||||||
|
return el.classList.contains("lang-switcher__option");
|
||||||
|
}
|
||||||
|
|
||||||
nav.querySelectorAll("a, button").forEach(function (el) {
|
nav.querySelectorAll("a, button").forEach(function (el) {
|
||||||
el.addEventListener("click", closeMenu);
|
el.addEventListener("click", function () {
|
||||||
|
if (shouldCloseNavOnControl(el)) closeMenu();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("resize", function () {
|
window.addEventListener("resize", function () {
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ de:
|
|||||||
logout_success: Abgemeldet
|
logout_success: Abgemeldet
|
||||||
password_current_incorrect: Das aktuelle Passwort ist falsch
|
password_current_incorrect: Das aktuelle Passwort ist falsch
|
||||||
password_too_short: Das neue Passwort muss mindestens 8 Zeichen lang sein
|
password_too_short: Das neue Passwort muss mindestens 8 Zeichen lang sein
|
||||||
|
password_too_long: Das neue Passwort darf höchstens 72 Zeichen lang sein
|
||||||
|
password_too_weak: Das neue Passwort muss mindestens 3 aus Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen enthalten
|
||||||
|
password_same_as_current: Das neue Passwort muss sich vom aktuellen unterscheiden
|
||||||
password_mismatch: Die Passwörter stimmen nicht überein
|
password_mismatch: Die Passwörter stimmen nicht überein
|
||||||
password_updated: Passwort aktualisiert
|
password_updated: Passwort aktualisiert
|
||||||
ops_acknowledged: Vorfall übernommen
|
ops_acknowledged: Vorfall übernommen
|
||||||
@@ -53,7 +56,7 @@ de:
|
|||||||
edit:
|
edit:
|
||||||
title: Passwort ändern
|
title: Passwort ändern
|
||||||
current_password_label: Aktuelles Passwort
|
current_password_label: Aktuelles Passwort
|
||||||
new_password_label: "Neues Passwort (mind. 8 Zeichen)"
|
new_password_label: "Neues Passwort (mind. 8, mindestens 3 Zeichenarten)"
|
||||||
confirm_password_label: Neues Passwort bestätigen
|
confirm_password_label: Neues Passwort bestätigen
|
||||||
submit: Passwort speichern
|
submit: Passwort speichern
|
||||||
cancel: Abbrechen
|
cancel: Abbrechen
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ en:
|
|||||||
logout_success: Signed out
|
logout_success: Signed out
|
||||||
password_current_incorrect: Current password is incorrect
|
password_current_incorrect: Current password is incorrect
|
||||||
password_too_short: The new password must be at least 8 characters long
|
password_too_short: The new password must be at least 8 characters long
|
||||||
|
password_too_long: New password cannot exceed 72 characters
|
||||||
|
password_too_weak: "New password must include at least 3 of: lowercase, uppercase, numbers and symbols"
|
||||||
|
password_same_as_current: New password must be different from the current password
|
||||||
password_mismatch: Passwords do not match
|
password_mismatch: Passwords do not match
|
||||||
password_updated: Password updated
|
password_updated: Password updated
|
||||||
ops_acknowledged: Incident acknowledged
|
ops_acknowledged: Incident acknowledged
|
||||||
@@ -53,7 +56,7 @@ en:
|
|||||||
edit:
|
edit:
|
||||||
title: Change password
|
title: Change password
|
||||||
current_password_label: Current password
|
current_password_label: Current password
|
||||||
new_password_label: "New password (min. 8 characters)"
|
new_password_label: "New password (min. 8, at least 3 character types)"
|
||||||
confirm_password_label: Confirm new password
|
confirm_password_label: Confirm new password
|
||||||
submit: Save password
|
submit: Save password
|
||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ es:
|
|||||||
logout_success: Sesión cerrada
|
logout_success: Sesión cerrada
|
||||||
password_current_incorrect: La contraseña actual no es correcta
|
password_current_incorrect: La contraseña actual no es correcta
|
||||||
password_too_short: La nueva contraseña debe tener al menos 8 caracteres
|
password_too_short: La nueva contraseña debe tener al menos 8 caracteres
|
||||||
|
password_too_long: La nueva contraseña no puede superar los 72 caracteres
|
||||||
|
password_too_weak: "La nueva contraseña debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos"
|
||||||
|
password_same_as_current: La nueva contraseña debe ser distinta de la actual
|
||||||
password_mismatch: Las contraseñas no coinciden
|
password_mismatch: Las contraseñas no coinciden
|
||||||
password_updated: Contraseña actualizada
|
password_updated: Contraseña actualizada
|
||||||
ops_acknowledged: Incidencia asumida
|
ops_acknowledged: Incidencia asumida
|
||||||
@@ -53,7 +56,7 @@ es:
|
|||||||
edit:
|
edit:
|
||||||
title: Cambiar contraseña
|
title: Cambiar contraseña
|
||||||
current_password_label: Contraseña actual
|
current_password_label: Contraseña actual
|
||||||
new_password_label: "Nueva contraseña (mín. 8 caracteres)"
|
new_password_label: "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)"
|
||||||
confirm_password_label: Confirma la nueva contraseña
|
confirm_password_label: Confirma la nueva contraseña
|
||||||
submit: Guardar contraseña
|
submit: Guardar contraseña
|
||||||
cancel: Cancelar
|
cancel: Cancelar
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ fr:
|
|||||||
logout_success: Déconnecté
|
logout_success: Déconnecté
|
||||||
password_current_incorrect: Le mot de passe actuel est incorrect
|
password_current_incorrect: Le mot de passe actuel est incorrect
|
||||||
password_too_short: Le nouveau mot de passe doit contenir au moins 8 caractères
|
password_too_short: Le nouveau mot de passe doit contenir au moins 8 caractères
|
||||||
|
password_too_long: Le nouveau mot de passe ne peut pas dépasser 72 caractères
|
||||||
|
password_too_weak: "Le nouveau mot de passe doit inclure au moins 3 parmi : minuscules, majuscules, chiffres et symboles"
|
||||||
|
password_same_as_current: "Le nouveau mot de passe doit être différent de l'actuel"
|
||||||
password_mismatch: Les mots de passe ne correspondent pas
|
password_mismatch: Les mots de passe ne correspondent pas
|
||||||
password_updated: Mot de passe mis à jour
|
password_updated: Mot de passe mis à jour
|
||||||
ops_acknowledged: Incident pris en charge
|
ops_acknowledged: Incident pris en charge
|
||||||
@@ -53,7 +56,7 @@ fr:
|
|||||||
edit:
|
edit:
|
||||||
title: Changer le mot de passe
|
title: Changer le mot de passe
|
||||||
current_password_label: Mot de passe actuel
|
current_password_label: Mot de passe actuel
|
||||||
new_password_label: "Nouveau mot de passe (min. 8 caractères)"
|
new_password_label: "Nouveau mot de passe (min. 8, au moins 3 types de caractères)"
|
||||||
confirm_password_label: Confirmer le nouveau mot de passe
|
confirm_password_label: Confirmer le nouveau mot de passe
|
||||||
submit: Enregistrer le mot de passe
|
submit: Enregistrer le mot de passe
|
||||||
cancel: Annuler
|
cancel: Annuler
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ it:
|
|||||||
logout_success: Disconnesso
|
logout_success: Disconnesso
|
||||||
password_current_incorrect: Password attuale non corretta
|
password_current_incorrect: Password attuale non corretta
|
||||||
password_too_short: La nuova password deve avere almeno 8 caratteri
|
password_too_short: La nuova password deve avere almeno 8 caratteri
|
||||||
|
password_too_long: La nuova password non può superare i 72 caratteri
|
||||||
|
password_too_weak: "La nuova password deve includere almeno 3 tra: minuscole, maiuscole, numeri e simboli"
|
||||||
|
password_same_as_current: La nuova password deve essere diversa da quella attuale
|
||||||
password_mismatch: Le password non coincidono
|
password_mismatch: Le password non coincidono
|
||||||
password_updated: Password aggiornata
|
password_updated: Password aggiornata
|
||||||
ops_acknowledged: Incidente preso in carico
|
ops_acknowledged: Incidente preso in carico
|
||||||
@@ -53,7 +56,7 @@ it:
|
|||||||
edit:
|
edit:
|
||||||
title: Cambia password
|
title: Cambia password
|
||||||
current_password_label: Password attuale
|
current_password_label: Password attuale
|
||||||
new_password_label: "Nuova password (min. 8 caratteri)"
|
new_password_label: "Nuova password (min. 8, almeno 3 tipi di caratteri)"
|
||||||
confirm_password_label: Conferma nuova password
|
confirm_password_label: Conferma nuova password
|
||||||
submit: Salva password
|
submit: Salva password
|
||||||
cancel: Annulla
|
cancel: Annulla
|
||||||
|
|||||||
@@ -1,4 +1,26 @@
|
|||||||
de:
|
de:
|
||||||
|
password_policy:
|
||||||
|
hint: "Mindestens 8 Zeichen, mit mindestens 3 aus: Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen."
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
user:
|
||||||
|
password: Passwort
|
||||||
|
admin_account:
|
||||||
|
password: Passwort
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "ist zu kurz (mindestens %{count} Zeichen)"
|
||||||
|
too_long: "ist zu lang (höchstens %{count} Zeichen)"
|
||||||
|
complexity: "muss mindestens 3 aus Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen enthalten"
|
||||||
|
admin_account:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "ist zu kurz (mindestens %{count} Zeichen)"
|
||||||
|
too_long: "ist zu lang (höchstens %{count} Zeichen)"
|
||||||
|
complexity: "muss mindestens 3 aus Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen enthalten"
|
||||||
club:
|
club:
|
||||||
back_to_club: "← Verein"
|
back_to_club: "← Verein"
|
||||||
sport_label: Hauptsportart
|
sport_label: Hauptsportart
|
||||||
@@ -600,10 +622,16 @@ de:
|
|||||||
welcome_back: Willkommen zurück!
|
welcome_back: Willkommen zurück!
|
||||||
invalid_credentials: E-Mail oder Passwort ungültig
|
invalid_credentials: E-Mail oder Passwort ungültig
|
||||||
logged_out: Abgemeldet
|
logged_out: Abgemeldet
|
||||||
|
unauthorized: Nicht autorisiert
|
||||||
|
invalid_token: Ungültiges Token
|
||||||
password_resets:
|
password_resets:
|
||||||
email_sent: Wenn die E-Mail registriert ist, erhältst du in Kürze einen Link zum Zurücksetzen des Passworts.
|
email_sent: Wenn die E-Mail registriert ist, erhältst du in Kürze einen Link zum Zurücksetzen des Passworts.
|
||||||
invalid_or_expired_link: Link ungültig oder abgelaufen. Fordere ein neues Zurücksetzen des Passworts an.
|
invalid_or_expired_link: Link ungültig oder abgelaufen. Fordere ein neues Zurücksetzen des Passworts an.
|
||||||
password_min_length: Das Passwort muss mindestens 8 Zeichen lang sein
|
password_min_length: Das Passwort muss mindestens 8 Zeichen lang sein
|
||||||
|
password_too_short: Das Passwort muss mindestens 8 Zeichen lang sein
|
||||||
|
password_too_long: Das Passwort darf höchstens 72 Zeichen lang sein
|
||||||
|
password_too_weak: Das Passwort muss mindestens 3 aus Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen enthalten
|
||||||
|
password_same_as_current: Das neue Passwort muss sich vom aktuellen unterscheiden
|
||||||
password_mismatch: Die Passwörter stimmen nicht überein
|
password_mismatch: Die Passwörter stimmen nicht überein
|
||||||
password_updated: Passwort aktualisiert. Du kannst dich jetzt anmelden.
|
password_updated: Passwort aktualisiert. Du kannst dich jetzt anmelden.
|
||||||
accounts:
|
accounts:
|
||||||
@@ -611,8 +639,12 @@ de:
|
|||||||
profile_updated: Profil aktualisiert.
|
profile_updated: Profil aktualisiert.
|
||||||
password_current_incorrect: Das aktuelle Passwort ist falsch
|
password_current_incorrect: Das aktuelle Passwort ist falsch
|
||||||
password_too_short: Das Passwort muss mindestens 8 Zeichen haben
|
password_too_short: Das Passwort muss mindestens 8 Zeichen haben
|
||||||
|
password_too_long: Das Passwort darf höchstens 72 Zeichen lang sein
|
||||||
|
password_too_weak: Das Passwort muss mindestens 3 aus Kleinbuchstaben, Großbuchstaben, Zahlen und Symbolen enthalten
|
||||||
|
password_same_as_current: Das neue Passwort muss sich vom aktuellen unterscheiden
|
||||||
password_mismatch: Die Passwörter stimmen nicht überein
|
password_mismatch: Die Passwörter stimmen nicht überein
|
||||||
password_updated: Passwort aktualisiert.
|
password_updated: Passwort aktualisiert.
|
||||||
|
password_update_failed: Passwort konnte nicht aktualisiert werden
|
||||||
replay:
|
replay:
|
||||||
download_unavailable: Download nicht verfügbar
|
download_unavailable: Download nicht verfügbar
|
||||||
not_available: Replay nicht verfügbar
|
not_available: Replay nicht verfügbar
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
en:
|
en:
|
||||||
|
password_policy:
|
||||||
|
hint: "At least 8 characters, including 3 of: lowercase, uppercase, numbers and symbols."
|
||||||
|
activerecord:
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "is too short (minimum is %{count} characters)"
|
||||||
|
too_long: "is too long (maximum is %{count} characters)"
|
||||||
|
complexity: "must include at least 3 of: lowercase letters, uppercase letters, numbers and symbols"
|
||||||
|
admin_account:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "is too short (minimum is %{count} characters)"
|
||||||
|
too_long: "is too long (maximum is %{count} characters)"
|
||||||
|
complexity: "must include at least 3 of: lowercase letters, uppercase letters, numbers and symbols"
|
||||||
club:
|
club:
|
||||||
back_to_club: "← Club"
|
back_to_club: "← Club"
|
||||||
sport_label: Main sport
|
sport_label: Main sport
|
||||||
@@ -600,10 +617,16 @@ en:
|
|||||||
welcome_back: Welcome back!
|
welcome_back: Welcome back!
|
||||||
invalid_credentials: Invalid email or password
|
invalid_credentials: Invalid email or password
|
||||||
logged_out: Logged out
|
logged_out: Logged out
|
||||||
|
unauthorized: Unauthorized
|
||||||
|
invalid_token: Invalid token
|
||||||
password_resets:
|
password_resets:
|
||||||
email_sent: If the email is registered, you'll receive a password reset link shortly.
|
email_sent: If the email is registered, you'll receive a password reset link shortly.
|
||||||
invalid_or_expired_link: Invalid or expired link. Request a new password reset.
|
invalid_or_expired_link: Invalid or expired link. Request a new password reset.
|
||||||
password_min_length: Password must be at least 8 characters
|
password_min_length: Password must be at least 8 characters
|
||||||
|
password_too_short: Password must be at least 8 characters
|
||||||
|
password_too_long: Password cannot exceed 72 characters
|
||||||
|
password_too_weak: "Password must include at least 3 of: lowercase, uppercase, numbers and symbols"
|
||||||
|
password_same_as_current: New password must be different from the current password
|
||||||
password_mismatch: Passwords don't match
|
password_mismatch: Passwords don't match
|
||||||
password_updated: Password updated. You can now log in.
|
password_updated: Password updated. You can now log in.
|
||||||
accounts:
|
accounts:
|
||||||
@@ -611,8 +634,12 @@ en:
|
|||||||
profile_updated: Profile updated.
|
profile_updated: Profile updated.
|
||||||
password_current_incorrect: Current password is incorrect
|
password_current_incorrect: Current password is incorrect
|
||||||
password_too_short: Password must be at least 8 characters
|
password_too_short: Password must be at least 8 characters
|
||||||
|
password_too_long: Password cannot exceed 72 characters
|
||||||
|
password_too_weak: "Password must include at least 3 of: lowercase, uppercase, numbers and symbols"
|
||||||
|
password_same_as_current: New password must be different from the current password
|
||||||
password_mismatch: Passwords do not match
|
password_mismatch: Passwords do not match
|
||||||
password_updated: Password updated.
|
password_updated: Password updated.
|
||||||
|
password_update_failed: Unable to update password
|
||||||
replay:
|
replay:
|
||||||
download_unavailable: Download not available
|
download_unavailable: Download not available
|
||||||
not_available: Replay not available
|
not_available: Replay not available
|
||||||
|
|||||||
@@ -1,4 +1,26 @@
|
|||||||
es:
|
es:
|
||||||
|
password_policy:
|
||||||
|
hint: "Mínimo 8 caracteres, con al menos 3 entre: minúsculas, mayúsculas, números y símbolos."
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
user:
|
||||||
|
password: Contraseña
|
||||||
|
admin_account:
|
||||||
|
password: Contraseña
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "es demasiado corta (mínimo %{count} caracteres)"
|
||||||
|
too_long: "es demasiado larga (máximo %{count} caracteres)"
|
||||||
|
complexity: "debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos"
|
||||||
|
admin_account:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "es demasiado corta (mínimo %{count} caracteres)"
|
||||||
|
too_long: "es demasiado larga (máximo %{count} caracteres)"
|
||||||
|
complexity: "debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos"
|
||||||
club:
|
club:
|
||||||
back_to_club: "← Club"
|
back_to_club: "← Club"
|
||||||
sport_label: Deporte principal
|
sport_label: Deporte principal
|
||||||
@@ -600,10 +622,16 @@ es:
|
|||||||
welcome_back: "¡Bienvenido de nuevo!"
|
welcome_back: "¡Bienvenido de nuevo!"
|
||||||
invalid_credentials: Correo o contraseña no válidos
|
invalid_credentials: Correo o contraseña no válidos
|
||||||
logged_out: Sesión cerrada
|
logged_out: Sesión cerrada
|
||||||
|
unauthorized: No autorizado
|
||||||
|
invalid_token: Token no válido
|
||||||
password_resets:
|
password_resets:
|
||||||
email_sent: Si el correo está registrado, recibirás en breve un enlace para restablecer la contraseña.
|
email_sent: Si el correo está registrado, recibirás en breve un enlace para restablecer la contraseña.
|
||||||
invalid_or_expired_link: Enlace no válido o caducado. Solicita un nuevo restablecimiento de contraseña.
|
invalid_or_expired_link: Enlace no válido o caducado. Solicita un nuevo restablecimiento de contraseña.
|
||||||
password_min_length: La contraseña debe tener al menos 8 caracteres
|
password_min_length: La contraseña debe tener al menos 8 caracteres
|
||||||
|
password_too_short: La contraseña debe tener al menos 8 caracteres
|
||||||
|
password_too_long: La contraseña no puede superar los 72 caracteres
|
||||||
|
password_too_weak: "La contraseña debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos"
|
||||||
|
password_same_as_current: La nueva contraseña debe ser distinta de la actual
|
||||||
password_mismatch: Las contraseñas no coinciden
|
password_mismatch: Las contraseñas no coinciden
|
||||||
password_updated: Contraseña actualizada. Ya puedes iniciar sesión.
|
password_updated: Contraseña actualizada. Ya puedes iniciar sesión.
|
||||||
accounts:
|
accounts:
|
||||||
@@ -611,8 +639,12 @@ es:
|
|||||||
profile_updated: Perfil actualizado.
|
profile_updated: Perfil actualizado.
|
||||||
password_current_incorrect: La contraseña actual no es correcta
|
password_current_incorrect: La contraseña actual no es correcta
|
||||||
password_too_short: La contraseña debe tener al menos 8 caracteres
|
password_too_short: La contraseña debe tener al menos 8 caracteres
|
||||||
|
password_too_long: La contraseña no puede superar los 72 caracteres
|
||||||
|
password_too_weak: "La contraseña debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos"
|
||||||
|
password_same_as_current: La nueva contraseña debe ser distinta de la actual
|
||||||
password_mismatch: Las contraseñas no coinciden
|
password_mismatch: Las contraseñas no coinciden
|
||||||
password_updated: Contraseña actualizada.
|
password_updated: Contraseña actualizada.
|
||||||
|
password_update_failed: No se pudo actualizar la contraseña
|
||||||
replay:
|
replay:
|
||||||
download_unavailable: Descarga no disponible
|
download_unavailable: Descarga no disponible
|
||||||
not_available: Repetición no disponible
|
not_available: Repetición no disponible
|
||||||
|
|||||||
@@ -1,4 +1,26 @@
|
|||||||
fr:
|
fr:
|
||||||
|
password_policy:
|
||||||
|
hint: "Au moins 8 caractères, avec au moins 3 parmi : minuscules, majuscules, chiffres et symboles."
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
user:
|
||||||
|
password: Mot de passe
|
||||||
|
admin_account:
|
||||||
|
password: Mot de passe
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "est trop court (minimum %{count} caractères)"
|
||||||
|
too_long: "est trop long (maximum %{count} caractères)"
|
||||||
|
complexity: "doit inclure au moins 3 parmi : minuscules, majuscules, chiffres et symboles"
|
||||||
|
admin_account:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "est trop court (minimum %{count} caractères)"
|
||||||
|
too_long: "est trop long (maximum %{count} caractères)"
|
||||||
|
complexity: "doit inclure au moins 3 parmi : minuscules, majuscules, chiffres et symboles"
|
||||||
club:
|
club:
|
||||||
back_to_club: "← Club"
|
back_to_club: "← Club"
|
||||||
sport_label: Sport principal
|
sport_label: Sport principal
|
||||||
@@ -600,10 +622,16 @@ fr:
|
|||||||
welcome_back: Bon retour !
|
welcome_back: Bon retour !
|
||||||
invalid_credentials: E-mail ou mot de passe invalide
|
invalid_credentials: E-mail ou mot de passe invalide
|
||||||
logged_out: Déconnecté
|
logged_out: Déconnecté
|
||||||
|
unauthorized: Non autorisé
|
||||||
|
invalid_token: Jeton invalide
|
||||||
password_resets:
|
password_resets:
|
||||||
email_sent: Si l'e-mail est enregistré, tu recevras bientôt un lien pour réinitialiser le mot de passe.
|
email_sent: Si l'e-mail est enregistré, tu recevras bientôt un lien pour réinitialiser le mot de passe.
|
||||||
invalid_or_expired_link: Lien invalide ou expiré. Demande une nouvelle réinitialisation du mot de passe.
|
invalid_or_expired_link: Lien invalide ou expiré. Demande une nouvelle réinitialisation du mot de passe.
|
||||||
password_min_length: Le mot de passe doit comporter au moins 8 caractères
|
password_min_length: Le mot de passe doit comporter au moins 8 caractères
|
||||||
|
password_too_short: Le mot de passe doit comporter au moins 8 caractères
|
||||||
|
password_too_long: Le mot de passe ne peut pas dépasser 72 caractères
|
||||||
|
password_too_weak: "Le mot de passe doit inclure au moins 3 parmi : minuscules, majuscules, chiffres et symboles"
|
||||||
|
password_same_as_current: "Le nouveau mot de passe doit être différent de l'actuel"
|
||||||
password_mismatch: Les mots de passe ne correspondent pas
|
password_mismatch: Les mots de passe ne correspondent pas
|
||||||
password_updated: Mot de passe mis à jour. Tu peux maintenant te connecter.
|
password_updated: Mot de passe mis à jour. Tu peux maintenant te connecter.
|
||||||
accounts:
|
accounts:
|
||||||
@@ -611,8 +639,12 @@ fr:
|
|||||||
profile_updated: Profil mis à jour.
|
profile_updated: Profil mis à jour.
|
||||||
password_current_incorrect: Le mot de passe actuel est incorrect
|
password_current_incorrect: Le mot de passe actuel est incorrect
|
||||||
password_too_short: Le mot de passe doit contenir au moins 8 caractères
|
password_too_short: Le mot de passe doit contenir au moins 8 caractères
|
||||||
|
password_too_long: Le mot de passe ne peut pas dépasser 72 caractères
|
||||||
|
password_too_weak: "Le mot de passe doit inclure au moins 3 parmi : minuscules, majuscules, chiffres et symboles"
|
||||||
|
password_same_as_current: "Le nouveau mot de passe doit être différent de l'actuel"
|
||||||
password_mismatch: Les mots de passe ne correspondent pas
|
password_mismatch: Les mots de passe ne correspondent pas
|
||||||
password_updated: Mot de passe mis à jour.
|
password_updated: Mot de passe mis à jour.
|
||||||
|
password_update_failed: Impossible de mettre à jour le mot de passe
|
||||||
replay:
|
replay:
|
||||||
download_unavailable: Téléchargement non disponible
|
download_unavailable: Téléchargement non disponible
|
||||||
not_available: Replay non disponible
|
not_available: Replay non disponible
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
it:
|
it:
|
||||||
|
password_policy:
|
||||||
|
hint: "Minimo 8 caratteri, con almeno 3 tra: minuscole, maiuscole, numeri e simboli."
|
||||||
|
activerecord:
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "è troppo corta (minimo %{count} caratteri)"
|
||||||
|
too_long: "è troppo lunga (massimo %{count} caratteri)"
|
||||||
|
complexity: "deve includere almeno 3 tra: lettere minuscole, maiuscole, numeri e simboli"
|
||||||
|
admin_account:
|
||||||
|
attributes:
|
||||||
|
password:
|
||||||
|
too_short: "è troppo corta (minimo %{count} caratteri)"
|
||||||
|
too_long: "è troppo lunga (massimo %{count} caratteri)"
|
||||||
|
complexity: "deve includere almeno 3 tra: lettere minuscole, maiuscole, numeri e simboli"
|
||||||
club:
|
club:
|
||||||
back_to_club: "← Società"
|
back_to_club: "← Società"
|
||||||
sport_label: Sport principale
|
sport_label: Sport principale
|
||||||
@@ -600,10 +617,19 @@ it:
|
|||||||
welcome_back: Bentornato!
|
welcome_back: Bentornato!
|
||||||
invalid_credentials: Email o password non validi
|
invalid_credentials: Email o password non validi
|
||||||
logged_out: Disconnesso
|
logged_out: Disconnesso
|
||||||
|
unauthorized: Non autorizzato
|
||||||
|
invalid_token: Token non valido
|
||||||
password_resets:
|
password_resets:
|
||||||
email_sent: Se l'email è registrata, riceverai a breve un link per reimpostare la password.
|
email_sent: Se l'email è registrata, riceverai a breve un link per reimpostare la password.
|
||||||
invalid_or_expired_link: Link non valido o scaduto. Richiedi un nuovo reset password.
|
invalid_or_expired_link: Link non valido o scaduto. Richiedi un nuovo reset password.
|
||||||
password_min_length: La password deve avere almeno 8 caratteri
|
password_min_length: La password deve avere almeno 8 caratteri
|
||||||
|
password_too_short: La password deve avere almeno 8 caratteri
|
||||||
|
password_too_long: La password non può superare i 72 caratteri
|
||||||
|
password_too_weak: "La password deve includere almeno 3 tra: minuscole, maiuscole, numeri e simboli"
|
||||||
|
password_same_as_current: La nuova password deve essere diversa da quella attuale
|
||||||
|
password_too_short: La password deve avere almeno 8 caratteri
|
||||||
|
password_too_long: La password non può superare i 72 caratteri
|
||||||
|
password_too_weak: "La password deve includere almeno 3 tra: minuscole, maiuscole, numeri e simboli"
|
||||||
password_mismatch: Le password non coincidono
|
password_mismatch: Le password non coincidono
|
||||||
password_updated: Password aggiornata. Ora puoi accedere.
|
password_updated: Password aggiornata. Ora puoi accedere.
|
||||||
accounts:
|
accounts:
|
||||||
@@ -611,8 +637,14 @@ it:
|
|||||||
profile_updated: Profilo aggiornato.
|
profile_updated: Profilo aggiornato.
|
||||||
password_current_incorrect: La password attuale non è corretta
|
password_current_incorrect: La password attuale non è corretta
|
||||||
password_too_short: La password deve avere almeno 8 caratteri
|
password_too_short: La password deve avere almeno 8 caratteri
|
||||||
|
password_too_long: La password non può superare i 72 caratteri
|
||||||
|
password_too_weak: "La password deve includere almeno 3 tra: minuscole, maiuscole, numeri e simboli"
|
||||||
|
password_same_as_current: La nuova password deve essere diversa da quella attuale
|
||||||
|
password_too_long: La password non può superare i 72 caratteri
|
||||||
|
password_too_weak: "La password deve includere almeno 3 tra: minuscole, maiuscole, numeri e simboli"
|
||||||
password_mismatch: Le password non coincidono
|
password_mismatch: Le password non coincidono
|
||||||
password_updated: Password aggiornata.
|
password_updated: Password aggiornata.
|
||||||
|
password_update_failed: Impossibile aggiornare la password
|
||||||
replay:
|
replay:
|
||||||
download_unavailable: Download non disponibile
|
download_unavailable: Download non disponibile
|
||||||
not_available: Replay non disponibile
|
not_available: Replay non disponibile
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ de:
|
|||||||
password_reset:
|
password_reset:
|
||||||
meta_title: "Neues Passwort — Match Live TV"
|
meta_title: "Neues Passwort — Match Live TV"
|
||||||
title: Neues Passwort wählen
|
title: Neues Passwort wählen
|
||||||
new_password_label: "Neues Passwort (min. 8 Zeichen)"
|
new_password_label: "Neues Passwort (mind. 8, mindestens 3 Zeichenarten)"
|
||||||
submit: Passwort speichern
|
submit: Passwort speichern
|
||||||
back_to_login: Zurück zur Anmeldung
|
back_to_login: Zurück zur Anmeldung
|
||||||
invitation:
|
invitation:
|
||||||
@@ -128,7 +128,7 @@ de:
|
|||||||
name_label: Name
|
name_label: Name
|
||||||
role_label: "Rolle: %{role}"
|
role_label: "Rolle: %{role}"
|
||||||
current_password_label: Aktuelles Passwort
|
current_password_label: Aktuelles Passwort
|
||||||
new_password_label: "Neues Passwort (mind. 8 Zeichen)"
|
new_password_label: "Neues Passwort (mind. 8, mindestens 3 Zeichenarten)"
|
||||||
save_profile: Profil speichern
|
save_profile: Profil speichern
|
||||||
save_password: Passwort aktualisieren
|
save_password: Passwort aktualisieren
|
||||||
common:
|
common:
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ en:
|
|||||||
password_reset:
|
password_reset:
|
||||||
meta_title: "New password — Match Live TV"
|
meta_title: "New password — Match Live TV"
|
||||||
title: Choose a new password
|
title: Choose a new password
|
||||||
new_password_label: "New password (min. 8 characters)"
|
new_password_label: "New password (min. 8, at least 3 character types)"
|
||||||
submit: Save password
|
submit: Save password
|
||||||
back_to_login: Back to login
|
back_to_login: Back to login
|
||||||
invitation:
|
invitation:
|
||||||
@@ -128,7 +128,7 @@ en:
|
|||||||
name_label: Name
|
name_label: Name
|
||||||
role_label: "Role: %{role}"
|
role_label: "Role: %{role}"
|
||||||
current_password_label: Current password
|
current_password_label: Current password
|
||||||
new_password_label: "New password (min. 8 characters)"
|
new_password_label: "New password (min. 8, at least 3 character types)"
|
||||||
save_profile: Save profile
|
save_profile: Save profile
|
||||||
save_password: Update password
|
save_password: Update password
|
||||||
common:
|
common:
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ es:
|
|||||||
password_reset:
|
password_reset:
|
||||||
meta_title: "Nueva contraseña — Match Live TV"
|
meta_title: "Nueva contraseña — Match Live TV"
|
||||||
title: Elige una nueva contraseña
|
title: Elige una nueva contraseña
|
||||||
new_password_label: "Nueva contraseña (mín. 8 caracteres)"
|
new_password_label: "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)"
|
||||||
submit: Guardar contraseña
|
submit: Guardar contraseña
|
||||||
back_to_login: Volver al inicio de sesión
|
back_to_login: Volver al inicio de sesión
|
||||||
invitation:
|
invitation:
|
||||||
@@ -128,7 +128,7 @@ es:
|
|||||||
name_label: Nombre
|
name_label: Nombre
|
||||||
role_label: "Rol: %{role}"
|
role_label: "Rol: %{role}"
|
||||||
current_password_label: Contraseña actual
|
current_password_label: Contraseña actual
|
||||||
new_password_label: "Nueva contraseña (mín. 8 caracteres)"
|
new_password_label: "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)"
|
||||||
save_profile: Guardar perfil
|
save_profile: Guardar perfil
|
||||||
save_password: Actualizar contraseña
|
save_password: Actualizar contraseña
|
||||||
common:
|
common:
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ fr:
|
|||||||
password_reset:
|
password_reset:
|
||||||
meta_title: "Nouveau mot de passe — Match Live TV"
|
meta_title: "Nouveau mot de passe — Match Live TV"
|
||||||
title: Choisissez un nouveau mot de passe
|
title: Choisissez un nouveau mot de passe
|
||||||
new_password_label: "Nouveau mot de passe (8 caractères min.)"
|
new_password_label: "Nouveau mot de passe (min. 8, au moins 3 types de caractères)"
|
||||||
submit: Enregistrer le mot de passe
|
submit: Enregistrer le mot de passe
|
||||||
back_to_login: Retour à la connexion
|
back_to_login: Retour à la connexion
|
||||||
invitation:
|
invitation:
|
||||||
@@ -128,7 +128,7 @@ fr:
|
|||||||
name_label: Nom
|
name_label: Nom
|
||||||
role_label: "Rôle : %{role}"
|
role_label: "Rôle : %{role}"
|
||||||
current_password_label: Mot de passe actuel
|
current_password_label: Mot de passe actuel
|
||||||
new_password_label: "Nouveau mot de passe (min. 8 caractères)"
|
new_password_label: "Nouveau mot de passe (min. 8, au moins 3 types de caractères)"
|
||||||
save_profile: Enregistrer le profil
|
save_profile: Enregistrer le profil
|
||||||
save_password: Mettre à jour le mot de passe
|
save_password: Mettre à jour le mot de passe
|
||||||
common:
|
common:
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ it:
|
|||||||
password_reset:
|
password_reset:
|
||||||
meta_title: "Nuova password — Match Live TV"
|
meta_title: "Nuova password — Match Live TV"
|
||||||
title: Scegli una nuova password
|
title: Scegli una nuova password
|
||||||
new_password_label: "Nuova password (min. 8 caratteri)"
|
new_password_label: "Nuova password (min. 8, almeno 3 tipi di caratteri)"
|
||||||
submit: Salva password
|
submit: Salva password
|
||||||
back_to_login: Torna al login
|
back_to_login: Torna al login
|
||||||
invitation:
|
invitation:
|
||||||
@@ -128,7 +128,7 @@ it:
|
|||||||
name_label: Nome
|
name_label: Nome
|
||||||
role_label: "Ruolo: %{role}"
|
role_label: "Ruolo: %{role}"
|
||||||
current_password_label: Password attuale
|
current_password_label: Password attuale
|
||||||
new_password_label: "Nuova password (min. 8 caratteri)"
|
new_password_label: "Nuova password (min. 8, almeno 3 tipi di caratteri)"
|
||||||
save_profile: Salva profilo
|
save_profile: Salva profilo
|
||||||
save_password: Aggiorna password
|
save_password: Aggiorna password
|
||||||
common:
|
common:
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ Rails.application.routes.draw do
|
|||||||
patch "password/reset", to: "password_resets#update"
|
patch "password/reset", to: "password_resets#update"
|
||||||
get "account", to: "accounts#show", as: :account
|
get "account", to: "accounts#show", as: :account
|
||||||
patch "account", to: "accounts#update"
|
patch "account", to: "accounts#update"
|
||||||
|
get "account/password", to: redirect("/account"), as: nil
|
||||||
patch "account/password", to: "accounts#update_password", as: :account_password
|
patch "account/password", to: "accounts#update_password", as: :account_password
|
||||||
get "clubs/new", to: "clubs#new", as: :new_club
|
get "clubs/new", to: "clubs#new", as: :new_club
|
||||||
post "clubs", to: "clubs#create"
|
post "clubs", to: "clubs#create"
|
||||||
|
|||||||
+4
-4
@@ -1,18 +1,18 @@
|
|||||||
load Rails.root.join("db/seeds/plans.rb")
|
load Rails.root.join("db/seeds/plans.rb")
|
||||||
|
|
||||||
AdminAccount.find_or_create_by!(username: "admin") do |a|
|
AdminAccount.find_or_create_by!(username: "admin") do |a|
|
||||||
a.password = "admin"
|
a.password = "AdminPass123"
|
||||||
end
|
end
|
||||||
|
|
||||||
coach = User.find_or_create_by!(email: "coach@matchlivetv.test") do |u|
|
coach = User.find_or_create_by!(email: "coach@matchlivetv.test") do |u|
|
||||||
u.name = "Coach Demo"
|
u.name = "Coach Demo"
|
||||||
u.password = "password123"
|
u.password = "Password123"
|
||||||
u.role = "coach"
|
u.role = "coach"
|
||||||
end
|
end
|
||||||
|
|
||||||
admin = User.find_or_create_by!(email: "admin@matchlivetv.test") do |u|
|
admin = User.find_or_create_by!(email: "admin@matchlivetv.test") do |u|
|
||||||
u.name = "Admin"
|
u.name = "Admin"
|
||||||
u.password = "password123"
|
u.password = "Password123"
|
||||||
u.role = "admin"
|
u.role = "admin"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -41,5 +41,5 @@ match = team.matches.find_or_create_by!(opponent_name: "ASD Eagles Pavia") do |m
|
|||||||
m.phase = "Semifinale"
|
m.phase = "Semifinale"
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "Seed OK: coach@matchlivetv.test / password123"
|
puts "Seed OK: coach@matchlivetv.test / Password123"
|
||||||
puts "Club: #{club.name}, Team: #{team.name}, Match: #{match.opponent_name}"
|
puts "Club: #{club.name}, Team: #{team.name}, Match: #{match.opponent_name}"
|
||||||
|
|||||||
+107
-16
@@ -199,6 +199,17 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
body.nav-menu-open .site-chrome {
|
body.nav-menu-open .site-chrome {
|
||||||
z-index: 1300;
|
z-index: 1300;
|
||||||
}
|
}
|
||||||
|
/* Keep the close control above the full-screen sheet; hide duplicate mast brand. */
|
||||||
|
body.nav-menu-open .site-masthead {
|
||||||
|
z-index: 1320;
|
||||||
|
background: transparent;
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
backdrop-filter: none;
|
||||||
|
}
|
||||||
|
body.nav-menu-open .mast-brand {
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
.nav-backdrop {
|
.nav-backdrop {
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -236,16 +247,50 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.nav-panel {
|
.nav-panel {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
|
min-height: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 72px 24px 32px;
|
padding: 16px 24px 32px;
|
||||||
padding-top: calc(72px + env(safe-area-inset-top, 0px));
|
padding-top: calc(16px + env(safe-area-inset-top, 0px));
|
||||||
padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px));
|
padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px));
|
||||||
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
.nav-mobile-head {
|
||||||
|
order: -1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 44px;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
padding: 0 52px 16px 0; /* room for the close (X) control on the right */
|
||||||
|
border-bottom: 1px solid #252530;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.nav-mobile-brand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
min-width: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.nav-mobile-brand:hover { text-decoration: none; opacity: 0.92; }
|
||||||
|
.nav-mobile-brand .brand { font-size: 1.05rem; }
|
||||||
|
.nav-mobile-brand-logo {
|
||||||
|
display: block;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
object-fit: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
.nav-panel > a,
|
.nav-panel > a,
|
||||||
.nav-panel .nav-link-item {
|
.nav-panel .nav-link-item {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -263,11 +308,13 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
}
|
}
|
||||||
.nav-actions {
|
.nav-actions {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 14px;
|
gap: 0;
|
||||||
margin-top: 24px;
|
margin-top: 8px;
|
||||||
padding: 24px 0 0;
|
padding: 0;
|
||||||
border-top: 1px solid #252530;
|
border-top: none;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.nav-actions .nav-link-item {
|
.nav-actions .nav-link-item {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -289,10 +336,14 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
.nav-lang {
|
.nav-lang {
|
||||||
margin-left: 0;
|
margin: 0;
|
||||||
margin-top: 4px;
|
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
width: 100%;
|
width: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.nav-lang .lang-switcher__menu {
|
||||||
|
/* Keep the list inside the open mobile sheet */
|
||||||
|
z-index: 1320;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,14 +393,22 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
gap: 8px 20px;
|
gap: 8px 20px;
|
||||||
}
|
}
|
||||||
|
.nav-mobile-head {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
.nav-mobile-brand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.nav-lang {
|
||||||
|
order: 2;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
.nav-actions {
|
.nav-actions {
|
||||||
|
order: 1;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
gap: 8px 12px;
|
gap: 8px 12px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.nav-lang {
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
.nav-backdrop { display: none !important; }
|
.nav-backdrop { display: none !important; }
|
||||||
}
|
}
|
||||||
.btn { display: inline-block; padding: 10px 18px; border-radius: 8px; font-weight: 700; font-size: 0.9rem; border: none; cursor: pointer; text-decoration: none; }
|
.btn { display: inline-block; padding: 10px 18px; border-radius: 8px; font-weight: 700; font-size: 0.9rem; border: none; cursor: pointer; text-decoration: none; }
|
||||||
@@ -1230,7 +1289,22 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.hero-split .hero-cta { flex-direction: column; }
|
.hero-split .hero-cta { flex-direction: column; }
|
||||||
.hero-split .hero-cta .btn { width: 100%; text-align: center; }
|
.hero-split .hero-cta .btn { width: 100%; text-align: center; }
|
||||||
}
|
}
|
||||||
.section { padding: 40px 0; }
|
.section {
|
||||||
|
padding-top: 40px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
}
|
||||||
|
/* Keep horizontal inset when .section shares a node with .wrap (padding shorthand must not win). */
|
||||||
|
.section.wrap {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.table-scroll {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
.section h2 { font-size: 1.6rem; margin: 0 0 20px; text-align: center; }
|
.section h2 { font-size: 1.6rem; margin: 0 0 20px; text-align: center; }
|
||||||
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }
|
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }
|
||||||
.step { background: #14141c; border: 1px solid #2a2a36; border-radius: 12px; padding: 22px; }
|
.step { background: #14141c; border: 1px solid #2a2a36; border-radius: 12px; padding: 22px; }
|
||||||
@@ -1363,7 +1437,7 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.site-footer__legal { flex: 1 1 100%; margin-top: 4px; }
|
.site-footer__legal { flex: 1 1 100%; margin-top: 4px; }
|
||||||
.site-footer__legal p { margin: 0 0 6px; line-height: 1.45; }
|
.site-footer__legal p { margin: 0 0 6px; line-height: 1.45; }
|
||||||
.site-footer__legal p:last-child { margin-bottom: 0; }
|
.site-footer__legal p:last-child { margin-bottom: 0; }
|
||||||
.compare-table { width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 0.9rem; }
|
.compare-table { width: 100%; min-width: 520px; border-collapse: collapse; margin-top: 0; font-size: 0.9rem; }
|
||||||
.compare-table th, .compare-table td { padding: 10px 12px; border-bottom: 1px solid #2a2a36; text-align: left; }
|
.compare-table th, .compare-table td { padding: 10px 12px; border-bottom: 1px solid #2a2a36; text-align: left; }
|
||||||
.compare-table th { color: #aaa; font-weight: 600; }
|
.compare-table th { color: #aaa; font-weight: 600; }
|
||||||
.billing-documents h2 { margin-top: 0; }
|
.billing-documents h2 { margin-top: 0; }
|
||||||
@@ -1372,11 +1446,14 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.card { background: #14141c; border: 1px solid #2a2a36; border-radius: 12px; padding: 20px; margin-bottom: 16px; }
|
.card { background: #14141c; border: 1px solid #2a2a36; border-radius: 12px; padding: 20px; margin-bottom: 16px; }
|
||||||
|
|
||||||
.seo-prose { max-width: 720px; margin: 0 auto; color: #bbb; line-height: 1.65; }
|
.seo-prose { max-width: 720px; margin: 0 auto; color: #bbb; line-height: 1.65; }
|
||||||
.seo-prose h2 { color: #fff; font-size: 1.25rem; margin: 28px 0 12px; }
|
.seo-prose h2 { color: #fff; font-size: 1.25rem; margin: 28px 0 12px; text-align: left; }
|
||||||
.seo-prose h2:first-child { margin-top: 0; }
|
.seo-prose h2:first-child { margin-top: 0; }
|
||||||
.seo-prose p { margin: 0 0 14px; }
|
.seo-prose p { margin: 0 0 14px; }
|
||||||
.seo-prose ul { margin: 0 0 16px; padding-left: 1.25rem; }
|
.seo-prose ul { margin: 0 0 16px; padding-left: 1.25rem; }
|
||||||
.seo-prose a { color: #e53935; }
|
.seo-prose a { color: #e53935; }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.seo-prose h2 { font-size: 1.15rem; line-height: 1.35; }
|
||||||
|
}
|
||||||
.seo-page .seo-lead { color: #aaa; max-width: 640px; line-height: 1.55; margin-bottom: 28px; }
|
.seo-page .seo-lead { color: #aaa; max-width: 640px; line-height: 1.55; margin-bottom: 28px; }
|
||||||
.faq-list { max-width: 720px; margin: 0 auto; }
|
.faq-list { max-width: 720px; margin: 0 auto; }
|
||||||
.faq-item {
|
.faq-item {
|
||||||
@@ -1412,7 +1489,8 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.legal-doc a { color: #e53935; }
|
.legal-doc a { color: #e53935; }
|
||||||
.legal-meta { color: #888; font-size: 0.88rem; margin-bottom: 24px; }
|
.legal-meta { color: #888; font-size: 0.88rem; margin-bottom: 24px; }
|
||||||
.legal-back { margin-top: 32px; }
|
.legal-back { margin-top: 32px; }
|
||||||
.legal-table { width: 100%; border-collapse: collapse; margin: 12px 0 16px; font-size: 0.88rem; }
|
.legal-doc .table-scroll { margin: 12px 0 16px; }
|
||||||
|
.legal-table { width: 100%; min-width: 560px; border-collapse: collapse; margin: 0; font-size: 0.88rem; }
|
||||||
.legal-table th, .legal-table td { border: 1px solid #2a2a36; padding: 10px 12px; text-align: left; vertical-align: top; }
|
.legal-table th, .legal-table td { border: 1px solid #2a2a36; padding: 10px 12px; text-align: left; vertical-align: top; }
|
||||||
.legal-table th { background: #14141c; color: #ccc; }
|
.legal-table th { background: #14141c; color: #ccc; }
|
||||||
.legal-accept {
|
.legal-accept {
|
||||||
@@ -1447,6 +1525,19 @@ body.nav-menu-open { overflow: hidden; }
|
|||||||
.auth-forgot a { color: #e53935; }
|
.auth-forgot a { color: #e53935; }
|
||||||
table.data { width: 100%; border-collapse: collapse; }
|
table.data { width: 100%; border-collapse: collapse; }
|
||||||
table.data th, table.data td { padding: 8px; border-bottom: 1px solid #2a2a36; text-align: left; }
|
table.data th, table.data td { padding: 8px; border-bottom: 1px solid #2a2a36; text-align: left; }
|
||||||
|
/* Wide roster/match tables: scroll inside the card instead of expanding the page. */
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.card:has(table.data),
|
||||||
|
.team-streaming-staff:has(table.data),
|
||||||
|
.billing-documents:has(table.data) {
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
table.data {
|
||||||
|
min-width: 520px;
|
||||||
|
}
|
||||||
|
}
|
||||||
input, select {
|
input, select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 12px 14px;
|
padding: 12px 14px;
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe PasswordComplexity do
|
||||||
|
describe ".violation" do
|
||||||
|
it "accepts a password with 3 character classes" do
|
||||||
|
expect(described_class.violation("NewPass123")).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "accepts symbols instead of one letter class" do
|
||||||
|
expect(described_class.violation("newpass1!")).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "rejects passwords that are too short" do
|
||||||
|
expect(described_class.violation("Ab1!")).to eq(:too_short)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "rejects passwords with fewer than 3 classes" do
|
||||||
|
expect(described_class.violation("password123")).to eq(:too_weak)
|
||||||
|
expect(described_class.violation("PASSWORD123")).to eq(:too_weak)
|
||||||
|
expect(described_class.violation("Password")).to eq(:too_weak)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".same_as_current?" do
|
||||||
|
let!(:user) { User.create!(email: "same@example.com", name: "Same", password: "Password123", role: "coach") }
|
||||||
|
|
||||||
|
it "detects when the new password matches the current one" do
|
||||||
|
expect(described_class.same_as_current?(user, "Password123")).to eq(true)
|
||||||
|
expect(described_class.same_as_current?(user, "OtherPass123")).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "User validation" do
|
||||||
|
it "blocks weak passwords on create" do
|
||||||
|
user = User.new(email: "weak@example.com", name: "Weak", password: "password123", role: "coach")
|
||||||
|
expect(user).not_to be_valid
|
||||||
|
expect(user.errors[:password]).to be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows strong passwords on create" do
|
||||||
|
user = User.new(email: "strong@example.com", name: "Strong", password: "NewPass123", role: "coach")
|
||||||
|
expect(user).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
RSpec.describe "Account API", type: :request do
|
RSpec.describe "Account API", type: :request do
|
||||||
let!(:user) { User.create!(email: "account@example.com", name: "Account User", password: "password123", role: "coach") }
|
let!(:user) { User.create!(email: "account@example.com", name: "Account User", password: "Password123", role: "coach") }
|
||||||
let(:auth_headers) do
|
let(:auth_headers) do
|
||||||
post "/api/v1/auth/login", params: { email: user.email, password: "password123" }
|
post "/api/v1/auth/login", params: { email: user.email, password: "Password123" }
|
||||||
token = JSON.parse(response.body).fetch("access_token")
|
token = JSON.parse(response.body).fetch("access_token")
|
||||||
{ "Authorization" => "Bearer #{token}" }
|
{ "Authorization" => "Bearer #{token}" }
|
||||||
end
|
end
|
||||||
@@ -40,25 +40,63 @@ RSpec.describe "Account API", type: :request do
|
|||||||
it "changes the password with the current password" do
|
it "changes the password with the current password" do
|
||||||
patch "/api/v1/account/password",
|
patch "/api/v1/account/password",
|
||||||
params: {
|
params: {
|
||||||
current_password: "password123",
|
current_password: "Password123",
|
||||||
password: "newpass123",
|
password: "NewPass123",
|
||||||
password_confirmation: "newpass123"
|
password_confirmation: "NewPass123"
|
||||||
},
|
},
|
||||||
headers: auth_headers
|
headers: auth_headers
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(user.reload.authenticate("newpass123")).to be_truthy
|
expect(user.reload.authenticate("NewPass123")).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects an incorrect current password" do
|
it "rejects an incorrect current password" do
|
||||||
patch "/api/v1/account/password",
|
patch "/api/v1/account/password",
|
||||||
params: {
|
params: {
|
||||||
current_password: "wrong",
|
current_password: "wrong",
|
||||||
password: "newpass123",
|
password: "NewPass123",
|
||||||
password_confirmation: "newpass123"
|
password_confirmation: "NewPass123"
|
||||||
},
|
},
|
||||||
headers: auth_headers
|
headers: auth_headers
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
expect(user.reload.authenticate("password123")).to be_truthy
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "rejects a password that fails complexity rules" do
|
||||||
|
patch "/api/v1/account/password",
|
||||||
|
params: {
|
||||||
|
current_password: "Password123",
|
||||||
|
password: "newpass123",
|
||||||
|
password_confirmation: "newpass123"
|
||||||
|
},
|
||||||
|
headers: auth_headers.merge("Accept-Language" => "en")
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(JSON.parse(response.body)["error"]).to match(/3 of/i)
|
||||||
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "rejects reusing the current password" do
|
||||||
|
patch "/api/v1/account/password",
|
||||||
|
params: {
|
||||||
|
current_password: "Password123",
|
||||||
|
password: "Password123",
|
||||||
|
password_confirmation: "Password123"
|
||||||
|
},
|
||||||
|
headers: auth_headers.merge("Accept-Language" => "en")
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(JSON.parse(response.body)["error"]).to match(/different/i)
|
||||||
|
expect(user.reload.authenticate("Password123")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "localizes password errors from Accept-Language" do
|
||||||
|
patch "/api/v1/account/password",
|
||||||
|
params: {
|
||||||
|
current_password: "Password123",
|
||||||
|
password: "Password123",
|
||||||
|
password_confirmation: "Password123"
|
||||||
|
},
|
||||||
|
headers: auth_headers.merge("Accept-Language" => "it")
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(JSON.parse(response.body)["error"]).to eq("La nuova password deve essere diversa da quella attuale")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -77,5 +115,13 @@ RSpec.describe "Account API", type: :request do
|
|||||||
}.not_to change { ActionMailer::Base.deliveries.size }
|
}.not_to change { ActionMailer::Base.deliveries.size }
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "localizes the response message from Accept-Language" do
|
||||||
|
post "/api/v1/auth/password/forgot",
|
||||||
|
params: { email: user.email },
|
||||||
|
headers: { "Accept-Language" => "fr" }
|
||||||
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(JSON.parse(response.body)["message"]).to include("réinitialiser")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
RSpec.describe "Auth API", type: :request do
|
RSpec.describe "Auth API", type: :request do
|
||||||
let!(:user) { User.create!(email: "test@example.com", name: "Test", password: "password123", role: "coach") }
|
let!(:user) { User.create!(email: "test@example.com", name: "Test", password: "Password123", role: "coach") }
|
||||||
|
|
||||||
it "logs in with valid credentials" do
|
it "logs in with valid credentials" do
|
||||||
post "/api/v1/auth/login", params: { email: user.email, password: "password123" }
|
post "/api/v1/auth/login", params: { email: user.email, password: "Password123" }
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(JSON.parse(response.body)).to have_key("access_token")
|
expect(JSON.parse(response.body)).to have_key("access_token")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ Solo se la società vuole il **proprio** canale invece di Match Live TV:
|
|||||||
|
|
||||||
Nella home app (**Partite**):
|
Nella home app (**Partite**):
|
||||||
|
|
||||||
- **Partita programmata** — scegli dal calendario una gara già inserita (sito o app)
|
|
||||||
- **Nuova partita** — programma data/ora oppure **Avvia subito** senza orario
|
- **Nuova partita** — programma data/ora oppure **Avvia subito** senza orario
|
||||||
|
- Oppure tocca una gara già in calendario (sito o app)
|
||||||
|
|
||||||
Poi tocca la card o conferma dal foglio: si apre il wizard (Partita → Trasmissione → …).
|
Poi conferma dal foglio o tocca la card: si apre il wizard (Partita → Trasmissione → …).
|
||||||
|
|
||||||
## 4. Avvia diretta
|
## 4. Avvia diretta
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Gap Android → iOS: allineamento app nativa
|
# Gap Android → iOS: allineamento app nativa
|
||||||
|
|
||||||
Documento operativo per continuare su **Mac** lo sviluppo iOS e rilasciare un’app **allineata ad Android `2.0.5-native`**.
|
Documento operativo per continuare su **Mac** lo sviluppo iOS e rilasciare un’app **allineata ad Android**.
|
||||||
|
|
||||||
**Aggiornato:** 24 luglio 2026
|
**Aggiornato:** 8 agosto 2026
|
||||||
**Riferimento Android (produzione / telefono / Play):** `2.0.5-native` (`versionCode` **26**), API `https://www.matchlivetv.it`
|
**Riferimento Android (produzione / telefono / Play):** `2.0.10-native` (`versionCode` **31**), API `https://www.matchlivetv.it`
|
||||||
**Stato iOS attuale:** marketing `2.0.5`, build `26` — i18n **allineato** (Login, hub, sheet/dialog, wizard, broadcast)
|
**Stato iOS attuale:** marketing `2.0.10`, build `31` — i18n **allineato** (Login, hub, sheet/dialog, wizard, broadcast, account/forgot)
|
||||||
|
|
||||||
Obiettivo iOS: **stessa copertura lingua** di Android (Login, hub, sheet/dialog, wizard, broadcast) + bump versione, **senza** i bug di sessione/crash già risolti su Android 2.0.5.
|
Obiettivo iOS: **stessa copertura lingua** di Android (Login, hub, sheet/dialog, wizard, broadcast, account) + bump versione, **senza** i bug di sessione/crash già risolti su Android.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ Queste sono regressioni/bug già visti su Android; **non ripeterli** su iOS.
|
|||||||
| Broadcast + score dialog | Sì | `broadcast.*` / `score.*` | **Fatto** |
|
| Broadcast + score dialog | Sì | `broadcast.*` / `score.*` | **Fatto** |
|
||||||
| Catalogo stringhe | `values*` (~230) | `AppLanguage.swift` L10n (~225, no FGS) | **Fatto** |
|
| Catalogo stringhe | `values*` (~230) | `AppLanguage.swift` L10n (~225, no FGS) | **Fatto** |
|
||||||
| Logout UI | Icona | Icona SF Symbol | **Fatto** |
|
| Logout UI | Icona | Icona SF Symbol | **Fatto** |
|
||||||
| Versione | `2.0.5-native` / **26** | `2.0.5` / **26** | **Fatto** |
|
| Versione | `2.0.10-native` / **31** | `2.0.10` / **31** | **Fatto** |
|
||||||
| RTMP ingest | `RtmpIngestUrl.kt` | `MediaUrl.swift` | OK |
|
| RTMP ingest | `RtmpIngestUrl.kt` | `MediaUrl.swift` | OK |
|
||||||
|
|
||||||
### Residui fuori scope Android (opzionali)
|
### Residui fuori scope Android (opzionali)
|
||||||
@@ -141,7 +141,7 @@ xcodebuild -project MatchLiveTv.xcodeproj -scheme MatchLiveTv \
|
|||||||
|
|
||||||
Nessuna modifica server richiesta.
|
Nessuna modifica server richiesta.
|
||||||
|
|
||||||
Versione store target: **`2.0.5` / build `26`** (parità con Android `2.0.5-native` / versionCode `26`).
|
Versione store target: **`2.0.10` / build `31`** (parità con Android `2.0.10-native` / versionCode `31`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# iOS — allineamento password policy + errori API localizzati
|
||||||
|
|
||||||
|
Documento operativo per **Cursor su Mac**: allineare l’app iOS a backend/Android dopo il ramo `feature/password-policy` (merge su `main`).
|
||||||
|
|
||||||
|
**Aggiornato:** 2026-08-08
|
||||||
|
**Android di riferimento:** `2.0.10-native` (`versionCode` **31**)
|
||||||
|
**iOS (allineato):** marketing `2.0.10` / build `31`
|
||||||
|
**API produzione:** `https://www.matchlivetv.it`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contesto (già in produzione backend dopo questo rilascio)
|
||||||
|
|
||||||
|
### Policy password (server)
|
||||||
|
|
||||||
|
Definita in `backend/app/models/concerns/password_complexity.rb`:
|
||||||
|
|
||||||
|
- minimo **8** caratteri, massimo **72** byte (bcrypt)
|
||||||
|
- almeno **3 classi su 4**: minuscole, maiuscole, numeri, simboli
|
||||||
|
- in **cambio password** e **reset**: la nuova password **non** può coincidere con quella attuale
|
||||||
|
|
||||||
|
Validazione ActiveModel su `User` / `AdminAccount`. Endpoint che la applicano:
|
||||||
|
|
||||||
|
| Endpoint | Note |
|
||||||
|
|----------|------|
|
||||||
|
| `PATCH /api/v1/account/password` | App native + stessi codici errore |
|
||||||
|
| `PATCH /account/password` (web) | Flash I18n |
|
||||||
|
| reset password pubblico | Stesse regole |
|
||||||
|
| registrazione (`auth/register`) | Validazione modello |
|
||||||
|
|
||||||
|
### Errori API localizzati
|
||||||
|
|
||||||
|
`ApplicationController#set_api_locale` legge, in ordine:
|
||||||
|
|
||||||
|
1. header `X-Locale`
|
||||||
|
2. `Accept-Language`
|
||||||
|
3. `I18n.default_locale` (fallback; **retrocompatibile** se l’app vecchia non manda nulla)
|
||||||
|
|
||||||
|
Risposta invariata: `{ "error": "<messaggio già tradotto>" }` (o `{ "message": "..." }` su alcuni successi).
|
||||||
|
|
||||||
|
Chiavi rilevanti (`backend/config/locales/app.{it,en,fr,de,es}.yml`):
|
||||||
|
|
||||||
|
- `flash.accounts.password_too_short`
|
||||||
|
- `flash.accounts.password_too_long`
|
||||||
|
- `flash.accounts.password_too_weak`
|
||||||
|
- `flash.accounts.password_same_as_current`
|
||||||
|
- `flash.accounts.password_current_incorrect`
|
||||||
|
- `flash.accounts.password_mismatch`
|
||||||
|
- `flash.accounts.password_updated` / `name_required`
|
||||||
|
- analoghi in `flash.password_resets.*` e `flash.sessions.*`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stato iOS vs Android
|
||||||
|
|
||||||
|
| Area | Android 2.0.10 | iOS | Stato |
|
||||||
|
|------|----------------|-----|-------|
|
||||||
|
| Header `Accept-Language` su tutte le request API | OkHttp interceptor | `MatchLiveAPI.request` + `multipartPatch` | **OK** |
|
||||||
|
| Hint UI nuova password | `account_new_password` | `account.new.password` | **OK** |
|
||||||
|
| Schermata Account | AccountScreen | AccountScreen | **OK** |
|
||||||
|
| Forgot password | ForgotPasswordScreen | ForgotPasswordScreen | **OK** |
|
||||||
|
| Parsing errori API | body `error` | `APIError.friendlyHttpMessage` | **OK** |
|
||||||
|
| Client-side pre-check complessità | No | No | N/A (come Android) |
|
||||||
|
| Versione store | `2.0.10-native` / **31** | `2.0.10` / **31** | **OK** |
|
||||||
|
| Signup in-app | Non principale | Nessuna UI register | N/A (signup web) |
|
||||||
|
|
||||||
|
### File iOS
|
||||||
|
|
||||||
|
```
|
||||||
|
native/ios/MatchLiveTv/Data/API/MatchLiveAPI.swift
|
||||||
|
native/ios/MatchLiveTv/Core/AppLanguage.swift
|
||||||
|
native/ios/MatchLiveTv/UI/Account/AccountScreen.swift
|
||||||
|
native/ios/MatchLiveTv/UI/Login/ForgotPasswordScreen.swift
|
||||||
|
native/ios/MatchLiveTv/Resources/Info.plist
|
||||||
|
native/ios/generate_xcodeproj.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Criterio “fatto”
|
||||||
|
|
||||||
|
- [x] `Accept-Language` su login, me, account, change password, forgot (`MatchLiveAPI`)
|
||||||
|
- [x] Hint campo nuova password parla di “min. 8 / 3 tipi”
|
||||||
|
- [x] Catalogo stringhe account/forgot in it/en/fr/de/es
|
||||||
|
- [x] Versione bumpata a `2.0.10` / `31`
|
||||||
|
- [ ] QA manuale errori password in lingua UI (weak / same / mismatch / success)
|
||||||
|
|
||||||
|
Quando rilasci su TestFlight/App Store, conferma la build `31`.
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
*.iml
|
*.iml
|
||||||
/captures/
|
/captures/
|
||||||
/app/build/
|
/app/build/
|
||||||
|
/dist/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
keystore.properties
|
keystore.properties
|
||||||
keystore/
|
keystore/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.matchlivetv.match_live_tv.data
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.matchlivetv.match_live_tv.core.AppConfig
|
import com.matchlivetv.match_live_tv.core.AppConfig
|
||||||
|
import com.matchlivetv.match_live_tv.core.AppLocale
|
||||||
import com.matchlivetv.match_live_tv.core.TokenStore
|
import com.matchlivetv.match_live_tv.core.TokenStore
|
||||||
import com.matchlivetv.match_live_tv.data.api.MatchLiveApi
|
import com.matchlivetv.match_live_tv.data.api.MatchLiveApi
|
||||||
import com.matchlivetv.match_live_tv.data.cable.SessionCableService
|
import com.matchlivetv.match_live_tv.data.cable.SessionCableService
|
||||||
@@ -37,10 +38,20 @@ class AppContainer(context: Context) {
|
|||||||
accessToken?.let { header("Authorization", "Bearer $it") }
|
accessToken?.let { header("Authorization", "Bearer $it") }
|
||||||
header("Accept", "application/json")
|
header("Accept", "application/json")
|
||||||
header("Content-Type", "application/json")
|
header("Content-Type", "application/json")
|
||||||
|
header("Accept-Language", apiLanguageTag())
|
||||||
}.build()
|
}.build()
|
||||||
chain.proceed(request)
|
chain.proceed(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun apiLanguageTag(): String {
|
||||||
|
val tag = AppLocale.currentTag(appContext)
|
||||||
|
return if (tag.isBlank()) {
|
||||||
|
java.util.Locale.getDefault().language.ifBlank { "it" }
|
||||||
|
} else {
|
||||||
|
tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val okHttp = OkHttpClient.Builder()
|
private val okHttp = OkHttpClient.Builder()
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
.readTimeout(60, TimeUnit.SECONDS)
|
.readTimeout(60, TimeUnit.SECONDS)
|
||||||
|
|||||||
+1
-9
@@ -57,7 +57,6 @@ import com.matchlivetv.match_live_tv.ui.components.LanguagePickerDialog
|
|||||||
import com.matchlivetv.match_live_tv.ui.components.MatchLiveWordmark
|
import com.matchlivetv.match_live_tv.ui.components.MatchLiveWordmark
|
||||||
import com.matchlivetv.match_live_tv.ui.components.MatchPrimaryButton
|
import com.matchlivetv.match_live_tv.ui.components.MatchPrimaryButton
|
||||||
import com.matchlivetv.match_live_tv.ui.components.MatchScreenScaffold
|
import com.matchlivetv.match_live_tv.ui.components.MatchScreenScaffold
|
||||||
import com.matchlivetv.match_live_tv.ui.components.MatchSecondaryButton
|
|
||||||
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -237,18 +236,11 @@ fun MatchesScreen(
|
|||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
|
||||||
MatchSecondaryButton(
|
|
||||||
label = stringResource(R.string.matches_schedule).uppercase(),
|
|
||||||
onClick = { showScheduleSheet = true },
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
)
|
|
||||||
MatchPrimaryButton(
|
MatchPrimaryButton(
|
||||||
label = stringResource(R.string.matches_new).uppercase(),
|
label = stringResource(R.string.matches_new).uppercase(),
|
||||||
onClick = { showNewMatchSheet = true },
|
onClick = { showNewMatchSheet = true },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
activeTeam?.let { team ->
|
activeTeam?.let { team ->
|
||||||
TeamPickerBar(
|
TeamPickerBar(
|
||||||
|
|||||||
@@ -21,13 +21,12 @@
|
|||||||
<string name="login_error_generic">Anmeldung fehlgeschlagen</string>
|
<string name="login_error_generic">Anmeldung fehlgeschlagen</string>
|
||||||
<string name="matches_title">Spiele</string>
|
<string name="matches_title">Spiele</string>
|
||||||
<string name="matches_hello">Hallo, %1$s</string>
|
<string name="matches_hello">Hallo, %1$s</string>
|
||||||
<string name="matches_subtitle">Nimm einen laufenden Livestream wieder auf oder starte ein geplantes Spiel.</string>
|
<string name="matches_subtitle">Nimm einen laufenden Livestream wieder auf oder starte ein neues Spiel.</string>
|
||||||
<string name="matches_schedule">Geplantes Spiel</string>
|
|
||||||
<string name="matches_new">Neues Spiel</string>
|
<string name="matches_new">Neues Spiel</string>
|
||||||
<string name="matches_empty_title">Keine Spiele im Kalender</string>
|
<string name="matches_empty_title">Keine Spiele im Kalender</string>
|
||||||
<string name="matches_scheduled_title">Geplante Spiele</string>
|
<string name="matches_scheduled_title">Geplante Spiele</string>
|
||||||
<string name="matches_ready_title">Bereit zum Start</string>
|
<string name="matches_ready_title">Bereit zum Start</string>
|
||||||
<string name="matches_empty_hint">Plane ein Spiel oder starte ein neues mit «Neues Spiel».</string>
|
<string name="matches_empty_hint">Tippe auf «Neues Spiel», um im Voraus zu planen oder sofort zu starten.</string>
|
||||||
<string name="matches_active_team">Aktives Team: %1$s.</string>
|
<string name="matches_active_team">Aktives Team: %1$s.</string>
|
||||||
<string name="matches_multi_team_hint">Du hast mehrere Teams: prüfe die oben ausgewählte.</string>
|
<string name="matches_multi_team_hint">Du hast mehrere Teams: prüfe die oben ausgewählte.</string>
|
||||||
<string name="matches_no_other">Keine weiteren Spiele im Kalender.</string>
|
<string name="matches_no_other">Keine weiteren Spiele im Kalender.</string>
|
||||||
@@ -252,7 +251,7 @@ Dies kann nicht rückgängig gemacht werden.</string>
|
|||||||
<string name="account_name_label">Name</string>
|
<string name="account_name_label">Name</string>
|
||||||
<string name="account_role">Rolle: %1$s</string>
|
<string name="account_role">Rolle: %1$s</string>
|
||||||
<string name="account_current_password">Aktuelles Passwort</string>
|
<string name="account_current_password">Aktuelles Passwort</string>
|
||||||
<string name="account_new_password">Neues Passwort (mind. 8 Zeichen)</string>
|
<string name="account_new_password">Neues Passwort (mind. 8, mindestens 3 Zeichenarten)</string>
|
||||||
<string name="account_confirm_password">Passwort bestätigen</string>
|
<string name="account_confirm_password">Passwort bestätigen</string>
|
||||||
<string name="account_save_profile">Profil speichern</string>
|
<string name="account_save_profile">Profil speichern</string>
|
||||||
<string name="account_save_password">Passwort aktualisieren</string>
|
<string name="account_save_password">Passwort aktualisieren</string>
|
||||||
|
|||||||
@@ -21,13 +21,12 @@
|
|||||||
<string name="login_error_generic">Login failed</string>
|
<string name="login_error_generic">Login failed</string>
|
||||||
<string name="matches_title">Matches</string>
|
<string name="matches_title">Matches</string>
|
||||||
<string name="matches_hello">Hi, %1$s</string>
|
<string name="matches_hello">Hi, %1$s</string>
|
||||||
<string name="matches_subtitle">Resume a live stream or start a scheduled match.</string>
|
<string name="matches_subtitle">Resume a live stream or start a new match.</string>
|
||||||
<string name="matches_schedule">Scheduled match</string>
|
|
||||||
<string name="matches_new">New match</string>
|
<string name="matches_new">New match</string>
|
||||||
<string name="matches_empty_title">No matches on the calendar</string>
|
<string name="matches_empty_title">No matches on the calendar</string>
|
||||||
<string name="matches_scheduled_title">Scheduled matches</string>
|
<string name="matches_scheduled_title">Scheduled matches</string>
|
||||||
<string name="matches_ready_title">Ready to start</string>
|
<string name="matches_ready_title">Ready to start</string>
|
||||||
<string name="matches_empty_hint">Schedule a match or start a new one with «New match».</string>
|
<string name="matches_empty_hint">Tap «New match» to schedule ahead or start right away.</string>
|
||||||
<string name="matches_active_team">Active team: %1$s.</string>
|
<string name="matches_active_team">Active team: %1$s.</string>
|
||||||
<string name="matches_multi_team_hint">You have multiple teams: check the one selected above.</string>
|
<string name="matches_multi_team_hint">You have multiple teams: check the one selected above.</string>
|
||||||
<string name="matches_no_other">No other matches on the calendar.</string>
|
<string name="matches_no_other">No other matches on the calendar.</string>
|
||||||
@@ -252,7 +251,7 @@ This cannot be undone.</string>
|
|||||||
<string name="account_name_label">Name</string>
|
<string name="account_name_label">Name</string>
|
||||||
<string name="account_role">Role: %1$s</string>
|
<string name="account_role">Role: %1$s</string>
|
||||||
<string name="account_current_password">Current password</string>
|
<string name="account_current_password">Current password</string>
|
||||||
<string name="account_new_password">New password (min. 8 characters)</string>
|
<string name="account_new_password">New password (min. 8, at least 3 character types)</string>
|
||||||
<string name="account_confirm_password">Confirm password</string>
|
<string name="account_confirm_password">Confirm password</string>
|
||||||
<string name="account_save_profile">Save profile</string>
|
<string name="account_save_profile">Save profile</string>
|
||||||
<string name="account_save_password">Update password</string>
|
<string name="account_save_password">Update password</string>
|
||||||
|
|||||||
@@ -21,13 +21,12 @@
|
|||||||
<string name="login_error_generic">Error de acceso</string>
|
<string name="login_error_generic">Error de acceso</string>
|
||||||
<string name="matches_title">Partidos</string>
|
<string name="matches_title">Partidos</string>
|
||||||
<string name="matches_hello">Hola, %1$s</string>
|
<string name="matches_hello">Hola, %1$s</string>
|
||||||
<string name="matches_subtitle">Reanuda un directo en curso o inicia un partido programado.</string>
|
<string name="matches_subtitle">Reanuda un directo en curso o inicia un nuevo partido.</string>
|
||||||
<string name="matches_schedule">Partido programado</string>
|
|
||||||
<string name="matches_new">Nuevo partido</string>
|
<string name="matches_new">Nuevo partido</string>
|
||||||
<string name="matches_empty_title">Ningún partido en el calendario</string>
|
<string name="matches_empty_title">Ningún partido en el calendario</string>
|
||||||
<string name="matches_scheduled_title">Partidos programados</string>
|
<string name="matches_scheduled_title">Partidos programados</string>
|
||||||
<string name="matches_ready_title">Listos para empezar</string>
|
<string name="matches_ready_title">Listos para empezar</string>
|
||||||
<string name="matches_empty_hint">Programa un partido o inicia uno nuevo con «Nuevo partido».</string>
|
<string name="matches_empty_hint">Toca «Nuevo partido» para programar con antelación o empezar ya.</string>
|
||||||
<string name="matches_active_team">Equipo activo: %1$s.</string>
|
<string name="matches_active_team">Equipo activo: %1$s.</string>
|
||||||
<string name="matches_multi_team_hint">Tienes varios equipos: comprueba el seleccionado arriba.</string>
|
<string name="matches_multi_team_hint">Tienes varios equipos: comprueba el seleccionado arriba.</string>
|
||||||
<string name="matches_no_other">Ningún otro partido en el calendario.</string>
|
<string name="matches_no_other">Ningún otro partido en el calendario.</string>
|
||||||
@@ -252,7 +251,7 @@ Esta acción no se puede deshacer.</string>
|
|||||||
<string name="account_name_label">Nombre</string>
|
<string name="account_name_label">Nombre</string>
|
||||||
<string name="account_role">Rol: %1$s</string>
|
<string name="account_role">Rol: %1$s</string>
|
||||||
<string name="account_current_password">Contraseña actual</string>
|
<string name="account_current_password">Contraseña actual</string>
|
||||||
<string name="account_new_password">Nueva contraseña (mín. 8 caracteres)</string>
|
<string name="account_new_password">Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)</string>
|
||||||
<string name="account_confirm_password">Confirmar contraseña</string>
|
<string name="account_confirm_password">Confirmar contraseña</string>
|
||||||
<string name="account_save_profile">Guardar perfil</string>
|
<string name="account_save_profile">Guardar perfil</string>
|
||||||
<string name="account_save_password">Actualizar contraseña</string>
|
<string name="account_save_password">Actualizar contraseña</string>
|
||||||
|
|||||||
@@ -21,13 +21,12 @@
|
|||||||
<string name="login_error_generic">Échec de la connexion</string>
|
<string name="login_error_generic">Échec de la connexion</string>
|
||||||
<string name="matches_title">Matchs</string>
|
<string name="matches_title">Matchs</string>
|
||||||
<string name="matches_hello">Bonjour, %1$s</string>
|
<string name="matches_hello">Bonjour, %1$s</string>
|
||||||
<string name="matches_subtitle">Reprenez un direct en cours ou démarrez un match programmé.</string>
|
<string name="matches_subtitle">Reprenez un direct en cours ou démarrez un nouveau match.</string>
|
||||||
<string name="matches_schedule">Match programmé</string>
|
|
||||||
<string name="matches_new">Nouveau match</string>
|
<string name="matches_new">Nouveau match</string>
|
||||||
<string name="matches_empty_title">Aucun match au calendrier</string>
|
<string name="matches_empty_title">Aucun match au calendrier</string>
|
||||||
<string name="matches_scheduled_title">Matchs programmés</string>
|
<string name="matches_scheduled_title">Matchs programmés</string>
|
||||||
<string name="matches_ready_title">Prêts à démarrer</string>
|
<string name="matches_ready_title">Prêts à démarrer</string>
|
||||||
<string name="matches_empty_hint">Programmez un match ou démarrez-en un avec « Nouveau match ».</string>
|
<string name="matches_empty_hint">Touchez « Nouveau match » pour planifier à l\'avance ou démarrer tout de suite.</string>
|
||||||
<string name="matches_active_team">Équipe active : %1$s.</string>
|
<string name="matches_active_team">Équipe active : %1$s.</string>
|
||||||
<string name="matches_multi_team_hint">Vous avez plusieurs équipes : vérifiez celle sélectionnée ci-dessus.</string>
|
<string name="matches_multi_team_hint">Vous avez plusieurs équipes : vérifiez celle sélectionnée ci-dessus.</string>
|
||||||
<string name="matches_no_other">Aucun autre match au calendrier.</string>
|
<string name="matches_no_other">Aucun autre match au calendrier.</string>
|
||||||
@@ -252,7 +251,7 @@ Cette action est irréversible.</string>
|
|||||||
<string name="account_name_label">Nom</string>
|
<string name="account_name_label">Nom</string>
|
||||||
<string name="account_role">Rôle : %1$s</string>
|
<string name="account_role">Rôle : %1$s</string>
|
||||||
<string name="account_current_password">Mot de passe actuel</string>
|
<string name="account_current_password">Mot de passe actuel</string>
|
||||||
<string name="account_new_password">Nouveau mot de passe (min. 8 caractères)</string>
|
<string name="account_new_password">Nouveau mot de passe (min. 8, au moins 3 types de caractères)</string>
|
||||||
<string name="account_confirm_password">Confirmer le mot de passe</string>
|
<string name="account_confirm_password">Confirmer le mot de passe</string>
|
||||||
<string name="account_save_profile">Enregistrer le profil</string>
|
<string name="account_save_profile">Enregistrer le profil</string>
|
||||||
<string name="account_save_password">Mettre à jour le mot de passe</string>
|
<string name="account_save_password">Mettre à jour le mot de passe</string>
|
||||||
|
|||||||
@@ -21,13 +21,12 @@
|
|||||||
<string name="login_error_generic">Login fallito</string>
|
<string name="login_error_generic">Login fallito</string>
|
||||||
<string name="matches_title">Partite</string>
|
<string name="matches_title">Partite</string>
|
||||||
<string name="matches_hello">Ciao, %1$s</string>
|
<string name="matches_hello">Ciao, %1$s</string>
|
||||||
<string name="matches_subtitle">Riprendi una diretta in corso o avvia una partita programmata.</string>
|
<string name="matches_subtitle">Riprendi una diretta in corso o avvia una nuova partita.</string>
|
||||||
<string name="matches_schedule">Partita programmata</string>
|
|
||||||
<string name="matches_new">Nuova partita</string>
|
<string name="matches_new">Nuova partita</string>
|
||||||
<string name="matches_empty_title">Nessuna partita in calendario</string>
|
<string name="matches_empty_title">Nessuna partita in calendario</string>
|
||||||
<string name="matches_scheduled_title">Partite programmate</string>
|
<string name="matches_scheduled_title">Partite programmate</string>
|
||||||
<string name="matches_ready_title">Pronte da avviare</string>
|
<string name="matches_ready_title">Pronte da avviare</string>
|
||||||
<string name="matches_empty_hint">Programma una partita o avviane una nuova con «Nuova partita».</string>
|
<string name="matches_empty_hint">Tocca «Nuova partita» per programmare in anticipo o avviare subito.</string>
|
||||||
<string name="matches_active_team">Squadra attiva: %1$s.</string>
|
<string name="matches_active_team">Squadra attiva: %1$s.</string>
|
||||||
<string name="matches_multi_team_hint">Hai più squadre: verifica quella selezionata sopra.</string>
|
<string name="matches_multi_team_hint">Hai più squadre: verifica quella selezionata sopra.</string>
|
||||||
<string name="matches_no_other">Nessuna altra partita in calendario.</string>
|
<string name="matches_no_other">Nessuna altra partita in calendario.</string>
|
||||||
@@ -252,7 +251,7 @@ L\'operazione non si può annullare.</string>
|
|||||||
<string name="account_name_label">Nome</string>
|
<string name="account_name_label">Nome</string>
|
||||||
<string name="account_role">Ruolo: %1$s</string>
|
<string name="account_role">Ruolo: %1$s</string>
|
||||||
<string name="account_current_password">Password attuale</string>
|
<string name="account_current_password">Password attuale</string>
|
||||||
<string name="account_new_password">Nuova password (min. 8 caratteri)</string>
|
<string name="account_new_password">Nuova password (min. 8, almeno 3 tipi di caratteri)</string>
|
||||||
<string name="account_confirm_password">Conferma password</string>
|
<string name="account_confirm_password">Conferma password</string>
|
||||||
<string name="account_save_profile">Salva profilo</string>
|
<string name="account_save_profile">Salva profilo</string>
|
||||||
<string name="account_save_password">Aggiorna password</string>
|
<string name="account_save_password">Aggiorna password</string>
|
||||||
|
|||||||
@@ -4,194 +4,194 @@
|
|||||||
classes = {};
|
classes = {};
|
||||||
objectVersion = 60;
|
objectVersion = 60;
|
||||||
objects = {
|
objects = {
|
||||||
4FC590728C2F47DE94AEADA3 /* MatchLiveTvApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveTvApp.swift; path = MatchLiveTv/App/MatchLiveTvApp.swift; sourceTree = "<group>"; };
|
5F5FC005B683447B82372E36 /* MatchLiveTvApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveTvApp.swift; path = MatchLiveTv/App/MatchLiveTvApp.swift; sourceTree = "<group>"; };
|
||||||
69F95F7CAF894139BA244AFF /* ApiInstant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiInstant.swift; path = MatchLiveTv/Core/ApiInstant.swift; sourceTree = "<group>"; };
|
C7D22FF2CF3D4230A7BAA60C /* ApiInstant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiInstant.swift; path = MatchLiveTv/Core/ApiInstant.swift; sourceTree = "<group>"; };
|
||||||
5E30D25B02704FAE9C0A4040 /* AppConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppConfig.swift; path = MatchLiveTv/Core/AppConfig.swift; sourceTree = "<group>"; };
|
9F180A1FA5DD4DB3BA7E3B41 /* AppConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppConfig.swift; path = MatchLiveTv/Core/AppConfig.swift; sourceTree = "<group>"; };
|
||||||
A59093CB86BB41FE9DF37182 /* AppLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppLanguage.swift; path = MatchLiveTv/Core/AppLanguage.swift; sourceTree = "<group>"; };
|
123A61DD4A6442728811488E /* AppLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppLanguage.swift; path = MatchLiveTv/Core/AppLanguage.swift; sourceTree = "<group>"; };
|
||||||
C00F6C82C9A04A50B1D34BA3 /* ColorHex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ColorHex.swift; path = MatchLiveTv/Core/ColorHex.swift; sourceTree = "<group>"; };
|
CDDF270D449A43F18399966D /* ColorHex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ColorHex.swift; path = MatchLiveTv/Core/ColorHex.swift; sourceTree = "<group>"; };
|
||||||
6F83B04D0BC84879A07C9BFE /* DeviceTelemetry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DeviceTelemetry.swift; path = MatchLiveTv/Core/DeviceTelemetry.swift; sourceTree = "<group>"; };
|
902831E3D87C46359F0D0A21 /* DeviceTelemetry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DeviceTelemetry.swift; path = MatchLiveTv/Core/DeviceTelemetry.swift; sourceTree = "<group>"; };
|
||||||
33DEE4675BAB413E9F69549B /* MediaUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MediaUrl.swift; path = MatchLiveTv/Core/MediaUrl.swift; sourceTree = "<group>"; };
|
ADBBD9C8DF9F4A47ACEFE7B1 /* MediaUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MediaUrl.swift; path = MatchLiveTv/Core/MediaUrl.swift; sourceTree = "<group>"; };
|
||||||
14FE2B5F844A482C91245755 /* ThermalState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalState.swift; path = MatchLiveTv/Core/Thermal/ThermalState.swift; sourceTree = "<group>"; };
|
AAC2A198868F4B4E9010F862 /* ThermalState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalState.swift; path = MatchLiveTv/Core/Thermal/ThermalState.swift; sourceTree = "<group>"; };
|
||||||
AA9DF2F1C5F04EA198286266 /* ThermalStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalStateManager.swift; path = MatchLiveTv/Core/Thermal/ThermalStateManager.swift; sourceTree = "<group>"; };
|
C9D84DE8EFA34B4CBDFF43F1 /* ThermalStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalStateManager.swift; path = MatchLiveTv/Core/Thermal/ThermalStateManager.swift; sourceTree = "<group>"; };
|
||||||
8EEFEB75DDB04C4986774D4B /* TokenStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TokenStore.swift; path = MatchLiveTv/Core/TokenStore.swift; sourceTree = "<group>"; };
|
31251A1297F24C70A14D8702 /* TokenStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TokenStore.swift; path = MatchLiveTv/Core/TokenStore.swift; sourceTree = "<group>"; };
|
||||||
C84694361A004982B4007CA5 /* UserFacingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UserFacingError.swift; path = MatchLiveTv/Core/UserFacingError.swift; sourceTree = "<group>"; };
|
1BEBDFA6B21041729156ADFA /* UserFacingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UserFacingError.swift; path = MatchLiveTv/Core/UserFacingError.swift; sourceTree = "<group>"; };
|
||||||
1AD71EE7F4A54818A6C427C9 /* ApiDtos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiDtos.swift; path = MatchLiveTv/Data/API/ApiDtos.swift; sourceTree = "<group>"; };
|
17E7568BD3D94B34A361F470 /* ApiDtos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiDtos.swift; path = MatchLiveTv/Data/API/ApiDtos.swift; sourceTree = "<group>"; };
|
||||||
610902FBCEB7478286C88C08 /* MatchLiveAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveAPI.swift; path = MatchLiveTv/Data/API/MatchLiveAPI.swift; sourceTree = "<group>"; };
|
99D52E8096064A359AAE3D47 /* MatchLiveAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveAPI.swift; path = MatchLiveTv/Data/API/MatchLiveAPI.swift; sourceTree = "<group>"; };
|
||||||
DD9687B43B5840DD96FAD1C9 /* AppContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppContainer.swift; path = MatchLiveTv/Data/AppContainer.swift; sourceTree = "<group>"; };
|
7FC98372F1BD474BB0365488 /* AppContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppContainer.swift; path = MatchLiveTv/Data/AppContainer.swift; sourceTree = "<group>"; };
|
||||||
905A6416560A4442AA7D2FCF /* ActionCableClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ActionCableClient.swift; path = MatchLiveTv/Data/Cable/ActionCableClient.swift; sourceTree = "<group>"; };
|
98526C26B2584F55AADF0FFF /* ActionCableClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ActionCableClient.swift; path = MatchLiveTv/Data/Cable/ActionCableClient.swift; sourceTree = "<group>"; };
|
||||||
9299E98557E04C5F8DC736F8 /* SessionCableService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionCableService.swift; path = MatchLiveTv/Data/Cable/SessionCableService.swift; sourceTree = "<group>"; };
|
50C70C614F3C45B9B824E465 /* SessionCableService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionCableService.swift; path = MatchLiveTv/Data/Cable/SessionCableService.swift; sourceTree = "<group>"; };
|
||||||
49E1D454901048A58DCE7C41 /* AuthRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AuthRepository.swift; path = MatchLiveTv/Data/Repository/AuthRepository.swift; sourceTree = "<group>"; };
|
EE0A49E8D59947448DAA7851 /* AuthRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AuthRepository.swift; path = MatchLiveTv/Data/Repository/AuthRepository.swift; sourceTree = "<group>"; };
|
||||||
A90696A40A584C5794938FDA /* MatchRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchRepository.swift; path = MatchLiveTv/Data/Repository/MatchRepository.swift; sourceTree = "<group>"; };
|
537FC2C063D341DF97A391B9 /* MatchRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchRepository.swift; path = MatchLiveTv/Data/Repository/MatchRepository.swift; sourceTree = "<group>"; };
|
||||||
2C3F8293D48D44A6A569F452 /* MatchSessionLauncher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchSessionLauncher.swift; path = MatchLiveTv/Data/Repository/MatchSessionLauncher.swift; sourceTree = "<group>"; };
|
813463F3E17D453EAA801739 /* MatchSessionLauncher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchSessionLauncher.swift; path = MatchLiveTv/Data/Repository/MatchSessionLauncher.swift; sourceTree = "<group>"; };
|
||||||
347DADA50AE44484ABF19903 /* ScoreRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreRepository.swift; path = MatchLiveTv/Data/Repository/ScoreRepository.swift; sourceTree = "<group>"; };
|
CCC8ECFD24A14054BDD984C3 /* ScoreRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreRepository.swift; path = MatchLiveTv/Data/Repository/ScoreRepository.swift; sourceTree = "<group>"; };
|
||||||
69794703A6D74DB9AA3D16A2 /* SessionRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionRepository.swift; path = MatchLiveTv/Data/Repository/SessionRepository.swift; sourceTree = "<group>"; };
|
87C01CC031C34343B3EBFF08 /* SessionRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionRepository.swift; path = MatchLiveTv/Data/Repository/SessionRepository.swift; sourceTree = "<group>"; };
|
||||||
D274E6DA2B7B47C9822FB517 /* ScoreController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreController.swift; path = MatchLiveTv/Data/Scoring/ScoreController.swift; sourceTree = "<group>"; };
|
B0B243B2A21344558626DF7F /* ScoreController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreController.swift; path = MatchLiveTv/Data/Scoring/ScoreController.swift; sourceTree = "<group>"; };
|
||||||
E4BAEE4AB7834E19BA57C4A1 /* WizardSessionHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardSessionHolder.swift; path = MatchLiveTv/Data/WizardSessionHolder.swift; sourceTree = "<group>"; };
|
81CA0BDC6EE44C4290D7E483 /* WizardSessionHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardSessionHolder.swift; path = MatchLiveTv/Data/WizardSessionHolder.swift; sourceTree = "<group>"; };
|
||||||
1060DB32269548BE895EFA7F /* MatchHubFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchHubFilter.swift; path = MatchLiveTv/Domain/MatchHubFilter.swift; sourceTree = "<group>"; };
|
951A7265EF5C41A9A12DD86A /* MatchHubFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchHubFilter.swift; path = MatchLiveTv/Domain/MatchHubFilter.swift; sourceTree = "<group>"; };
|
||||||
CA265A4F2CAA41DA8F68A35C /* MatchScoringRules.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScoringRules.swift; path = MatchLiveTv/Domain/MatchScoringRules.swift; sourceTree = "<group>"; };
|
18445F0E4070424F86D55556 /* MatchScoringRules.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScoringRules.swift; path = MatchLiveTv/Domain/MatchScoringRules.swift; sourceTree = "<group>"; };
|
||||||
0381775B0B1D4378A8BF289A /* Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Models.swift; path = MatchLiveTv/Domain/Models.swift; sourceTree = "<group>"; };
|
61FCDE0B00FB485CB9B09110 /* Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Models.swift; path = MatchLiveTv/Domain/Models.swift; sourceTree = "<group>"; };
|
||||||
85D4CBF80A8F447790235E7C /* ScoreState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreState.swift; path = MatchLiveTv/Domain/ScoreState.swift; sourceTree = "<group>"; };
|
EA08E23008964D02AB59377E /* ScoreState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreState.swift; path = MatchLiveTv/Domain/ScoreState.swift; sourceTree = "<group>"; };
|
||||||
2EA97648294C4D98B3D85EFD /* BroadcastModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastModels.swift; path = MatchLiveTv/Streaming/BroadcastModels.swift; sourceTree = "<group>"; };
|
C9975D8D02CF4FA0A47696DD /* BroadcastModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastModels.swift; path = MatchLiveTv/Streaming/BroadcastModels.swift; sourceTree = "<group>"; };
|
||||||
FA4A1042B44B41E0AE768E0C /* BroadcastOrientationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastOrientationPolicy.swift; path = MatchLiveTv/Streaming/BroadcastOrientationPolicy.swift; sourceTree = "<group>"; };
|
B2432C46DFBA4322887D8C59 /* BroadcastOrientationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastOrientationPolicy.swift; path = MatchLiveTv/Streaming/BroadcastOrientationPolicy.swift; sourceTree = "<group>"; };
|
||||||
97DF04B6B21743BC9615E634 /* BroadcastVideoOrientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastVideoOrientation.swift; path = MatchLiveTv/Streaming/BroadcastVideoOrientation.swift; sourceTree = "<group>"; };
|
A43B670D8BE94F66B38885C8 /* BroadcastVideoOrientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastVideoOrientation.swift; path = MatchLiveTv/Streaming/BroadcastVideoOrientation.swift; sourceTree = "<group>"; };
|
||||||
1B031A4D51634E96BBD3D8DA /* LiveBroadcastCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastCoordinator.swift; path = MatchLiveTv/Streaming/LiveBroadcastCoordinator.swift; sourceTree = "<group>"; };
|
F438E7E164F44C7B856C4808 /* LiveBroadcastCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastCoordinator.swift; path = MatchLiveTv/Streaming/LiveBroadcastCoordinator.swift; sourceTree = "<group>"; };
|
||||||
BC442280384D4194A66F25D2 /* LiveBroadcastEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastEngine.swift; path = MatchLiveTv/Streaming/LiveBroadcastEngine.swift; sourceTree = "<group>"; };
|
C6D684B88BEB440F8D331D3D /* LiveBroadcastEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastEngine.swift; path = MatchLiveTv/Streaming/LiveBroadcastEngine.swift; sourceTree = "<group>"; };
|
||||||
EF6E8429A9DF475E9C964A2A /* CompactScoreboardElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompactScoreboardElement.swift; path = MatchLiveTv/Streaming/Overlay/CompactScoreboardElement.swift; sourceTree = "<group>"; };
|
78104BD8D9044B659F33B02F /* CompactScoreboardElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompactScoreboardElement.swift; path = MatchLiveTv/Streaming/Overlay/CompactScoreboardElement.swift; sourceTree = "<group>"; };
|
||||||
AA419130C5A248DCA3B4A016 /* OverlayCanvasRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayCanvasRenderer.swift; path = MatchLiveTv/Streaming/Overlay/OverlayCanvasRenderer.swift; sourceTree = "<group>"; };
|
A8048B96407947C7BA4222E8 /* OverlayCanvasRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayCanvasRenderer.swift; path = MatchLiveTv/Streaming/Overlay/OverlayCanvasRenderer.swift; sourceTree = "<group>"; };
|
||||||
8CF76F8D690C405D9FCC4B8E /* OverlayLogoCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayLogoCache.swift; path = MatchLiveTv/Streaming/Overlay/OverlayLogoCache.swift; sourceTree = "<group>"; };
|
B5BF3429BFBA4DB3BDBD721D /* OverlayLogoCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayLogoCache.swift; path = MatchLiveTv/Streaming/Overlay/OverlayLogoCache.swift; sourceTree = "<group>"; };
|
||||||
E1A1C8A803FB4CA1BA741E57 /* OverlayMappings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayMappings.swift; path = MatchLiveTv/Streaming/Overlay/OverlayMappings.swift; sourceTree = "<group>"; };
|
509414F2274844F4B9A956C3 /* OverlayMappings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayMappings.swift; path = MatchLiveTv/Streaming/Overlay/OverlayMappings.swift; sourceTree = "<group>"; };
|
||||||
195EFB33D08D484489FD721B /* OverlayRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayRenderer.swift; path = MatchLiveTv/Streaming/Overlay/OverlayRenderer.swift; sourceTree = "<group>"; };
|
59E96B1417004CD3BC247C0F /* OverlayRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayRenderer.swift; path = MatchLiveTv/Streaming/Overlay/OverlayRenderer.swift; sourceTree = "<group>"; };
|
||||||
DB0DF408F60149008C9644C0 /* OverlayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayState.swift; path = MatchLiveTv/Streaming/Overlay/OverlayState.swift; sourceTree = "<group>"; };
|
2DDC7305F3B549D0B7646B14 /* OverlayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OverlayState.swift; path = MatchLiveTv/Streaming/Overlay/OverlayState.swift; sourceTree = "<group>"; };
|
||||||
E9F0583912AA42F787751A7F /* ScoreboardElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreboardElement.swift; path = MatchLiveTv/Streaming/Overlay/ScoreboardElement.swift; sourceTree = "<group>"; };
|
9D645FD397CD40DDA859F160 /* ScoreboardElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreboardElement.swift; path = MatchLiveTv/Streaming/Overlay/ScoreboardElement.swift; sourceTree = "<group>"; };
|
||||||
FB19CB746D6146D9ABD1A1C4 /* SponsorElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SponsorElement.swift; path = MatchLiveTv/Streaming/Overlay/SponsorElement.swift; sourceTree = "<group>"; };
|
18B95E0D21B0407FA6723720 /* SponsorElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SponsorElement.swift; path = MatchLiveTv/Streaming/Overlay/SponsorElement.swift; sourceTree = "<group>"; };
|
||||||
CD8C48EA12DB45FF978FA049 /* WatermarkElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WatermarkElement.swift; path = MatchLiveTv/Streaming/Overlay/WatermarkElement.swift; sourceTree = "<group>"; };
|
31750F1B9E294337BDBD5B56 /* WatermarkElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WatermarkElement.swift; path = MatchLiveTv/Streaming/Overlay/WatermarkElement.swift; sourceTree = "<group>"; };
|
||||||
838A41F3BF1E42BDAA2CE2E6 /* LivePreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LivePreviewView.swift; path = MatchLiveTv/Streaming/Preview/LivePreviewView.swift; sourceTree = "<group>"; };
|
46CE696CAB994E2C8E399776 /* LivePreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LivePreviewView.swift; path = MatchLiveTv/Streaming/Preview/LivePreviewView.swift; sourceTree = "<group>"; };
|
||||||
2074992AD4E94430B9524FB3 /* StreamVideoPreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StreamVideoPreset.swift; path = MatchLiveTv/Streaming/StreamVideoPreset.swift; sourceTree = "<group>"; };
|
8C2A2F7BAC2B4AC69E8BEAF7 /* StreamVideoPreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StreamVideoPreset.swift; path = MatchLiveTv/Streaming/StreamVideoPreset.swift; sourceTree = "<group>"; };
|
||||||
B51507FF41FB4B80831D70E3 /* BroadcastControlsOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastControlsOverlay.swift; path = MatchLiveTv/UI/Broadcast/BroadcastControlsOverlay.swift; sourceTree = "<group>"; };
|
4419E10415414556B7C58458 /* AccountScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AccountScreen.swift; path = MatchLiveTv/UI/Account/AccountScreen.swift; sourceTree = "<group>"; };
|
||||||
8EA7E4972BB74FDD884370D0 /* BroadcastScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastScreen.swift; path = MatchLiveTv/UI/Broadcast/BroadcastScreen.swift; sourceTree = "<group>"; };
|
E860A0E35362427DA84F8972 /* BroadcastControlsOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastControlsOverlay.swift; path = MatchLiveTv/UI/Broadcast/BroadcastControlsOverlay.swift; sourceTree = "<group>"; };
|
||||||
CC2B124ACD024538B20863B8 /* LiveScoreActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveScoreActions.swift; path = MatchLiveTv/UI/Broadcast/LiveScoreActions.swift; sourceTree = "<group>"; };
|
71816F0D99E44551839474CE /* BroadcastScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastScreen.swift; path = MatchLiveTv/UI/Broadcast/BroadcastScreen.swift; sourceTree = "<group>"; };
|
||||||
31B0AEBA3A0140D2BC9698DC /* MatchLiveWordmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveWordmark.swift; path = MatchLiveTv/UI/Components/MatchLiveWordmark.swift; sourceTree = "<group>"; };
|
4637B286559F4BC294018AC5 /* LiveScoreActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveScoreActions.swift; path = MatchLiveTv/UI/Broadcast/LiveScoreActions.swift; sourceTree = "<group>"; };
|
||||||
0C84054AB3574CC5B8056694 /* MatchPrimaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchPrimaryButton.swift; path = MatchLiveTv/UI/Components/MatchPrimaryButton.swift; sourceTree = "<group>"; };
|
2FF23D4B51AE4DA5B99D4021 /* MatchLiveWordmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchLiveWordmark.swift; path = MatchLiveTv/UI/Components/MatchLiveWordmark.swift; sourceTree = "<group>"; };
|
||||||
D7434175C1E849D7A8308896 /* MatchScreenScaffold.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScreenScaffold.swift; path = MatchLiveTv/UI/Components/MatchScreenScaffold.swift; sourceTree = "<group>"; };
|
6F04C9EAB5984F938EC60BF4 /* MatchPrimaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchPrimaryButton.swift; path = MatchLiveTv/UI/Components/MatchPrimaryButton.swift; sourceTree = "<group>"; };
|
||||||
3DE0F41386A741B2A6FC538B /* MatchSecondaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchSecondaryButton.swift; path = MatchLiveTv/UI/Components/MatchSecondaryButton.swift; sourceTree = "<group>"; };
|
39F3C00B63534E6AA6D8A90A /* MatchScreenScaffold.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScreenScaffold.swift; path = MatchLiveTv/UI/Components/MatchScreenScaffold.swift; sourceTree = "<group>"; };
|
||||||
1F6A499FE7D94EF498DA9A84 /* MatchStatusBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchStatusBadge.swift; path = MatchLiveTv/UI/Components/MatchStatusBadge.swift; sourceTree = "<group>"; };
|
C7403EB9DBD8459A93D9E2D8 /* MatchSecondaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchSecondaryButton.swift; path = MatchLiveTv/UI/Components/MatchSecondaryButton.swift; sourceTree = "<group>"; };
|
||||||
E13972C3F4664A89AE13D5D8 /* AccountScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AccountScreen.swift; path = MatchLiveTv/UI/Account/AccountScreen.swift; sourceTree = "<group>"; };
|
34BB2251A67E401A9F1E789E /* MatchStatusBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchStatusBadge.swift; path = MatchLiveTv/UI/Components/MatchStatusBadge.swift; sourceTree = "<group>"; };
|
||||||
DDF38B8E56394DEBA022F812 /* ForgotPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ForgotPasswordScreen.swift; path = MatchLiveTv/UI/Login/ForgotPasswordScreen.swift; sourceTree = "<group>"; };
|
AF8C38306C6F420DBC42DA2A /* ForgotPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ForgotPasswordScreen.swift; path = MatchLiveTv/UI/Login/ForgotPasswordScreen.swift; sourceTree = "<group>"; };
|
||||||
DA51BC65490E421AA3D16F02 /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LoginScreen.swift; path = MatchLiveTv/UI/Login/LoginScreen.swift; sourceTree = "<group>"; };
|
E124B3B49FC34520805CCC97 /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LoginScreen.swift; path = MatchLiveTv/UI/Login/LoginScreen.swift; sourceTree = "<group>"; };
|
||||||
0A439BB96CCB4C038EEF44DD /* MatchesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchesScreen.swift; path = MatchLiveTv/UI/Matches/MatchesScreen.swift; sourceTree = "<group>"; };
|
56A95962EF2A4B8F821343D9 /* MatchesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchesScreen.swift; path = MatchLiveTv/UI/Matches/MatchesScreen.swift; sourceTree = "<group>"; };
|
||||||
5DD00428364442C6B8C55DDF /* AppNavHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppNavHost.swift; path = MatchLiveTv/UI/Navigation/AppNavHost.swift; sourceTree = "<group>"; };
|
866A83237E6943E89A165B9D /* AppNavHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppNavHost.swift; path = MatchLiveTv/UI/Navigation/AppNavHost.swift; sourceTree = "<group>"; };
|
||||||
9F958AB307244896BD8948D2 /* ModalRoutes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ModalRoutes.swift; path = MatchLiveTv/UI/Navigation/ModalRoutes.swift; sourceTree = "<group>"; };
|
464CF87BEA644025B2D14644 /* ModalRoutes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ModalRoutes.swift; path = MatchLiveTv/UI/Navigation/ModalRoutes.swift; sourceTree = "<group>"; };
|
||||||
21C2A6AB0E164C8CBDF9CF7F /* Routes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Routes.swift; path = MatchLiveTv/UI/Navigation/Routes.swift; sourceTree = "<group>"; };
|
B214C9B30C794F00A31B0D83 /* Routes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Routes.swift; path = MatchLiveTv/UI/Navigation/Routes.swift; sourceTree = "<group>"; };
|
||||||
1702AF57020940DEBF0F9BA0 /* BroadcastPermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastPermissions.swift; path = MatchLiveTv/UI/Permissions/BroadcastPermissions.swift; sourceTree = "<group>"; };
|
3BFB2F18615747B1A1C9E9B2 /* BroadcastPermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastPermissions.swift; path = MatchLiveTv/UI/Permissions/BroadcastPermissions.swift; sourceTree = "<group>"; };
|
||||||
3004C07E608644AFB636C0C5 /* SplashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SplashScreen.swift; path = MatchLiveTv/UI/Splash/SplashScreen.swift; sourceTree = "<group>"; };
|
D7C29F5731A142C3A12B6DCA /* SplashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SplashScreen.swift; path = MatchLiveTv/UI/Splash/SplashScreen.swift; sourceTree = "<group>"; };
|
||||||
DC39718A2EC74B078A0C5DE9 /* KeepScreenOn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = KeepScreenOn.swift; path = MatchLiveTv/UI/System/KeepScreenOn.swift; sourceTree = "<group>"; };
|
004F86D8E8BE47E589B923FA /* KeepScreenOn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = KeepScreenOn.swift; path = MatchLiveTv/UI/System/KeepScreenOn.swift; sourceTree = "<group>"; };
|
||||||
BCEB22897600469E93762209 /* ScreenOrientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScreenOrientation.swift; path = MatchLiveTv/UI/System/ScreenOrientation.swift; sourceTree = "<group>"; };
|
FF10FF45004F41AD82397DC9 /* ScreenOrientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScreenOrientation.swift; path = MatchLiveTv/UI/System/ScreenOrientation.swift; sourceTree = "<group>"; };
|
||||||
13BC17CE70034FEE97707B21 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShareSheet.swift; path = MatchLiveTv/UI/System/ShareSheet.swift; sourceTree = "<group>"; };
|
2B5C00419D09442FA8ED60F3 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShareSheet.swift; path = MatchLiveTv/UI/System/ShareSheet.swift; sourceTree = "<group>"; };
|
||||||
AAAD219E4FA94CF885472711 /* MatchColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchColors.swift; path = MatchLiveTv/UI/Theme/MatchColors.swift; sourceTree = "<group>"; };
|
D2996990D08341ABA52BE287 /* MatchColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchColors.swift; path = MatchLiveTv/UI/Theme/MatchColors.swift; sourceTree = "<group>"; };
|
||||||
29F84FF3F1E74E49A3EA5101 /* StepMatchScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepMatchScreen.swift; path = MatchLiveTv/UI/Wizard/StepMatchScreen.swift; sourceTree = "<group>"; };
|
EAB037B1369B454D84F6850D /* StepMatchScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepMatchScreen.swift; path = MatchLiveTv/UI/Wizard/StepMatchScreen.swift; sourceTree = "<group>"; };
|
||||||
1875AE0A77B94DF0921EE457 /* StepNetworkTestScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepNetworkTestScreen.swift; path = MatchLiveTv/UI/Wizard/StepNetworkTestScreen.swift; sourceTree = "<group>"; };
|
1079231B9A4E446AA9AD6C0A /* StepNetworkTestScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepNetworkTestScreen.swift; path = MatchLiveTv/UI/Wizard/StepNetworkTestScreen.swift; sourceTree = "<group>"; };
|
||||||
3168221266004A33BA35042C /* StepTransmissionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepTransmissionScreen.swift; path = MatchLiveTv/UI/Wizard/StepTransmissionScreen.swift; sourceTree = "<group>"; };
|
7EC0179FE6BC4323B1F9E1D3 /* StepTransmissionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StepTransmissionScreen.swift; path = MatchLiveTv/UI/Wizard/StepTransmissionScreen.swift; sourceTree = "<group>"; };
|
||||||
C97603C3A54342799CBD0C03 /* TeamBrandingEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TeamBrandingEditor.swift; path = MatchLiveTv/UI/Wizard/TeamBrandingEditor.swift; sourceTree = "<group>"; };
|
6FBBE0F1399840FFA0E7EF2E /* TeamBrandingEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TeamBrandingEditor.swift; path = MatchLiveTv/UI/Wizard/TeamBrandingEditor.swift; sourceTree = "<group>"; };
|
||||||
5AFEAFB3E8F047B9A2B0DD04 /* TeamColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TeamColorPicker.swift; path = MatchLiveTv/UI/Wizard/TeamColorPicker.swift; sourceTree = "<group>"; };
|
7001BB5D65B34280B306ECCF /* TeamColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TeamColorPicker.swift; path = MatchLiveTv/UI/Wizard/TeamColorPicker.swift; sourceTree = "<group>"; };
|
||||||
CE7A5A0E6D9A49EA95918E79 /* WizardComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardComponents.swift; path = MatchLiveTv/UI/Wizard/WizardComponents.swift; sourceTree = "<group>"; };
|
5B75DC6D0B2248B2A6C9AA66 /* WizardComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardComponents.swift; path = MatchLiveTv/UI/Wizard/WizardComponents.swift; sourceTree = "<group>"; };
|
||||||
68CB1416AC24491CAA4CE87A /* WizardShellScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardShellScreen.swift; path = MatchLiveTv/UI/Wizard/WizardShellScreen.swift; sourceTree = "<group>"; };
|
3170F3149C614EC38B417905 /* WizardShellScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WizardShellScreen.swift; path = MatchLiveTv/UI/Wizard/WizardShellScreen.swift; sourceTree = "<group>"; };
|
||||||
73BB032A0DD74458B0E716C6 /* ApiInstantTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiInstantTests.swift; path = MatchLiveTvTests/ApiInstantTests.swift; sourceTree = "<group>"; };
|
75FEB862C3A34BF8AC24052E /* ApiInstantTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiInstantTests.swift; path = MatchLiveTvTests/ApiInstantTests.swift; sourceTree = "<group>"; };
|
||||||
C186E88B35A0443494AE6E8E /* BroadcastOrientationPolicyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastOrientationPolicyTests.swift; path = MatchLiveTvTests/BroadcastOrientationPolicyTests.swift; sourceTree = "<group>"; };
|
E5CA1FE59BA14F76BA94C995 /* BroadcastOrientationPolicyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BroadcastOrientationPolicyTests.swift; path = MatchLiveTvTests/BroadcastOrientationPolicyTests.swift; sourceTree = "<group>"; };
|
||||||
5751DB993C52460D960B8067 /* LiveBroadcastCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastCoordinatorTests.swift; path = MatchLiveTvTests/LiveBroadcastCoordinatorTests.swift; sourceTree = "<group>"; };
|
1830F9A925334BA4B65D490E /* LiveBroadcastCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveBroadcastCoordinatorTests.swift; path = MatchLiveTvTests/LiveBroadcastCoordinatorTests.swift; sourceTree = "<group>"; };
|
||||||
0E243C00009048F6A778323C /* LiveScoreDialogHostTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveScoreDialogHostTests.swift; path = MatchLiveTvTests/LiveScoreDialogHostTests.swift; sourceTree = "<group>"; };
|
F4F8BF2514BB4F5185827B95 /* LiveScoreDialogHostTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LiveScoreDialogHostTests.swift; path = MatchLiveTvTests/LiveScoreDialogHostTests.swift; sourceTree = "<group>"; };
|
||||||
634AD5C2E53B4C098582284A /* MatchScoringRulesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScoringRulesTests.swift; path = MatchLiveTvTests/MatchScoringRulesTests.swift; sourceTree = "<group>"; };
|
8964CE287E2C4C2DB701497B /* MatchScoringRulesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MatchScoringRulesTests.swift; path = MatchLiveTvTests/MatchScoringRulesTests.swift; sourceTree = "<group>"; };
|
||||||
B7DE055717014393B3F62D5A /* ScoreActionDecodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreActionDecodeTests.swift; path = MatchLiveTvTests/ScoreActionDecodeTests.swift; sourceTree = "<group>"; };
|
10AD0F18190542818572CAEF /* ScoreActionDecodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreActionDecodeTests.swift; path = MatchLiveTvTests/ScoreActionDecodeTests.swift; sourceTree = "<group>"; };
|
||||||
C3C1AC6562ED4A908D7C8B0A /* ScoreControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreControllerTests.swift; path = MatchLiveTvTests/ScoreControllerTests.swift; sourceTree = "<group>"; };
|
6DF142EBF33B45739BA8E42C /* ScoreControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScoreControllerTests.swift; path = MatchLiveTvTests/ScoreControllerTests.swift; sourceTree = "<group>"; };
|
||||||
610A4D03FA384F0287AAF825 /* ThermalAdaptationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalAdaptationTests.swift; path = MatchLiveTvTests/ThermalAdaptationTests.swift; sourceTree = "<group>"; };
|
377A2D2B2DA440AFB0CE2298 /* ThermalAdaptationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ThermalAdaptationTests.swift; path = MatchLiveTvTests/ThermalAdaptationTests.swift; sourceTree = "<group>"; };
|
||||||
F68654552B254000B6F0BE97 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MatchLiveTv/Resources/Assets.xcassets; sourceTree = "<group>"; };
|
2146FBAC1D7F4FF7B47D360F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MatchLiveTv/Resources/Assets.xcassets; sourceTree = "<group>"; };
|
||||||
1255FF9134D246ECBE1DF72C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = MatchLiveTv/Resources/Info.plist; sourceTree = "<group>"; };
|
8588711837244B19B84BA0B3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = MatchLiveTv/Resources/Info.plist; sourceTree = "<group>"; };
|
||||||
6DFD25C0855F482DBEFD8757 /* it.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/it.lproj; sourceTree = "<group>"; };
|
857C036B5B5C43368506DD8B /* it.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/it.lproj; sourceTree = "<group>"; };
|
||||||
12C3FA28B28146B9A8E3A70A /* en.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/en.lproj; sourceTree = "<group>"; };
|
3A6F9AAB5A1249BBB4FC02E6 /* en.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/en.lproj; sourceTree = "<group>"; };
|
||||||
5D760AAFB9C34DACBFC2387A /* fr.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/fr.lproj; sourceTree = "<group>"; };
|
30B07E7585A7408EA47C8633 /* fr.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/fr.lproj; sourceTree = "<group>"; };
|
||||||
85B0F928887C44128434974E /* de.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/de.lproj; sourceTree = "<group>"; };
|
EEFE07D4B6FD44199A5B9C25 /* de.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/de.lproj; sourceTree = "<group>"; };
|
||||||
E907C350C3E5410FB4A2038D /* es.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/es.lproj; sourceTree = "<group>"; };
|
2ACAF5B8A617427C8CBF56AD /* es.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MatchLiveTv/Resources/es.lproj; sourceTree = "<group>"; };
|
||||||
6FF24BB96E9C40F6A9F6E25A /* MatchLiveTv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatchLiveTv.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
CE0F9D7D5EE749E8AAE6AB43 /* MatchLiveTv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatchLiveTv.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8F679C9C03AE47D6A028DBAC /* MatchLiveTvTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatchLiveTvTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
3FC0CC8155BE469ABB420DC5 /* MatchLiveTvTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MatchLiveTvTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
31418599149E4F7684EABE04 /* HaishinKit */ = {isa = XCSwiftPackageProductDependency; package = 4901BAD7A32F4CFD805083BE; productName = HaishinKit; };
|
74B2BB60EC504F4E9CAFDDC8 /* HaishinKit */ = {isa = XCSwiftPackageProductDependency; package = 294A8F0AC0E54F1EB302705C; productName = HaishinKit; };
|
||||||
1712041BB26748D78A1D8F49 /* RTMPHaishinKit */ = {isa = XCSwiftPackageProductDependency; package = 4901BAD7A32F4CFD805083BE; productName = RTMPHaishinKit; };
|
8D1C04B6B7DF4271AC84A016 /* RTMPHaishinKit */ = {isa = XCSwiftPackageProductDependency; package = 294A8F0AC0E54F1EB302705C; productName = RTMPHaishinKit; };
|
||||||
F7624153A1C84C218B602FFB /* MatchLiveTvApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC590728C2F47DE94AEADA3 /* MatchLiveTvApp.swift */; };
|
65D33C32CF91408B91AFF5D4 /* MatchLiveTvApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FC005B683447B82372E36 /* MatchLiveTvApp.swift */; };
|
||||||
D973F2B503854C6AA61A1559 /* ApiInstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69F95F7CAF894139BA244AFF /* ApiInstant.swift */; };
|
F4C4427723C34532AFA1F798 /* ApiInstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D22FF2CF3D4230A7BAA60C /* ApiInstant.swift */; };
|
||||||
FE2D8C8359CC4DA189DF5DC6 /* AppConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E30D25B02704FAE9C0A4040 /* AppConfig.swift */; };
|
E75C942B73594F1484927866 /* AppConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F180A1FA5DD4DB3BA7E3B41 /* AppConfig.swift */; };
|
||||||
B607A146AE754F6A819FB186 /* AppLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59093CB86BB41FE9DF37182 /* AppLanguage.swift */; };
|
38BACC0DAAA147EB8955A60C /* AppLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123A61DD4A6442728811488E /* AppLanguage.swift */; };
|
||||||
B0D93B493FD0427CA72F5862 /* ColorHex.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00F6C82C9A04A50B1D34BA3 /* ColorHex.swift */; };
|
99B3D05A3D704DA1A513689F /* ColorHex.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDF270D449A43F18399966D /* ColorHex.swift */; };
|
||||||
3C223B19BA2149C5B7E5CC5A /* DeviceTelemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F83B04D0BC84879A07C9BFE /* DeviceTelemetry.swift */; };
|
65EB1857F331469BAC9A18D7 /* DeviceTelemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 902831E3D87C46359F0D0A21 /* DeviceTelemetry.swift */; };
|
||||||
3D119DE97DE5452D903F364C /* MediaUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33DEE4675BAB413E9F69549B /* MediaUrl.swift */; };
|
2F393B5FCD244E65B13C97A3 /* MediaUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADBBD9C8DF9F4A47ACEFE7B1 /* MediaUrl.swift */; };
|
||||||
8ABF00BDC15C400A9089FC28 /* ThermalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14FE2B5F844A482C91245755 /* ThermalState.swift */; };
|
5620C77D9A5B47F3BA0741E4 /* ThermalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC2A198868F4B4E9010F862 /* ThermalState.swift */; };
|
||||||
7D2649B9131F4DDA83F68B72 /* ThermalStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9DF2F1C5F04EA198286266 /* ThermalStateManager.swift */; };
|
D75CBE430CF947B1B8B0225B /* ThermalStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D84DE8EFA34B4CBDFF43F1 /* ThermalStateManager.swift */; };
|
||||||
AB71730B7CA24D3E8667BCFF /* TokenStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EEFEB75DDB04C4986774D4B /* TokenStore.swift */; };
|
A74ACBA3E07740E59502306F /* TokenStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31251A1297F24C70A14D8702 /* TokenStore.swift */; };
|
||||||
ADA58448C2344DADAA90F212 /* UserFacingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84694361A004982B4007CA5 /* UserFacingError.swift */; };
|
AA18CC40AAB249ECB8C88B85 /* UserFacingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BEBDFA6B21041729156ADFA /* UserFacingError.swift */; };
|
||||||
95F7871858C44379A62012BA /* ApiDtos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EE7F4A54818A6C427C9 /* ApiDtos.swift */; };
|
162DC182A26243599EEA862A /* ApiDtos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E7568BD3D94B34A361F470 /* ApiDtos.swift */; };
|
||||||
3FBBEF8DFF5E4F5D9E34C860 /* MatchLiveAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 610902FBCEB7478286C88C08 /* MatchLiveAPI.swift */; };
|
2A0825BF1DCC4DC2B1FBC236 /* MatchLiveAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99D52E8096064A359AAE3D47 /* MatchLiveAPI.swift */; };
|
||||||
91694276C76B438F8B52448F /* AppContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD9687B43B5840DD96FAD1C9 /* AppContainer.swift */; };
|
70D5E80900C14B0897F02BF8 /* AppContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FC98372F1BD474BB0365488 /* AppContainer.swift */; };
|
||||||
51D849AFAC8D4F57BEF05CAB /* ActionCableClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 905A6416560A4442AA7D2FCF /* ActionCableClient.swift */; };
|
9391C9EA0B834DC8956483DF /* ActionCableClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98526C26B2584F55AADF0FFF /* ActionCableClient.swift */; };
|
||||||
D771BABE58A3439CA1768F7F /* SessionCableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9299E98557E04C5F8DC736F8 /* SessionCableService.swift */; };
|
359A4FD093C84543AD4DA3B1 /* SessionCableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C70C614F3C45B9B824E465 /* SessionCableService.swift */; };
|
||||||
23C149E317BD416D9CF0B171 /* AuthRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E1D454901048A58DCE7C41 /* AuthRepository.swift */; };
|
59B045E87F2946B8BC8EA65A /* AuthRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE0A49E8D59947448DAA7851 /* AuthRepository.swift */; };
|
||||||
43C57FF23CB347AC99284468 /* MatchRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90696A40A584C5794938FDA /* MatchRepository.swift */; };
|
AECC36D80A0C411AB47D581A /* MatchRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537FC2C063D341DF97A391B9 /* MatchRepository.swift */; };
|
||||||
8661E674C82545C4AEC0A7CE /* MatchSessionLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C3F8293D48D44A6A569F452 /* MatchSessionLauncher.swift */; };
|
39335ED5DE5847E5904222AB /* MatchSessionLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 813463F3E17D453EAA801739 /* MatchSessionLauncher.swift */; };
|
||||||
E133D004CF0A4FF7A51A47B1 /* ScoreRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347DADA50AE44484ABF19903 /* ScoreRepository.swift */; };
|
470957DE79A84D9889F0663C /* ScoreRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCC8ECFD24A14054BDD984C3 /* ScoreRepository.swift */; };
|
||||||
72090ACA64CB4885BE7AB333 /* SessionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69794703A6D74DB9AA3D16A2 /* SessionRepository.swift */; };
|
66815B27A71244F791DE3C2F /* SessionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87C01CC031C34343B3EBFF08 /* SessionRepository.swift */; };
|
||||||
D80261301CA740568D8807D2 /* ScoreController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274E6DA2B7B47C9822FB517 /* ScoreController.swift */; };
|
244F331A033D4A32A0DC46CB /* ScoreController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0B243B2A21344558626DF7F /* ScoreController.swift */; };
|
||||||
9ECD8B486DF84890BD39B108 /* WizardSessionHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4BAEE4AB7834E19BA57C4A1 /* WizardSessionHolder.swift */; };
|
6EB9973427144A28B857B49E /* WizardSessionHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81CA0BDC6EE44C4290D7E483 /* WizardSessionHolder.swift */; };
|
||||||
C217B8AD49D04976A6D7FC7E /* MatchHubFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1060DB32269548BE895EFA7F /* MatchHubFilter.swift */; };
|
454725D14B224276B06BCC67 /* MatchHubFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951A7265EF5C41A9A12DD86A /* MatchHubFilter.swift */; };
|
||||||
978AAF829F654537AC473F52 /* MatchScoringRules.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA265A4F2CAA41DA8F68A35C /* MatchScoringRules.swift */; };
|
C19C5E8152C44669AE5D8874 /* MatchScoringRules.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18445F0E4070424F86D55556 /* MatchScoringRules.swift */; };
|
||||||
032C790773A848B7A0434C67 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0381775B0B1D4378A8BF289A /* Models.swift */; };
|
20A6FAB1CB7F47C085B75A22 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FCDE0B00FB485CB9B09110 /* Models.swift */; };
|
||||||
A37BC192D6C9433F83FABAA8 /* ScoreState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D4CBF80A8F447790235E7C /* ScoreState.swift */; };
|
8723E1F8443A46B3AF49E8A3 /* ScoreState.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA08E23008964D02AB59377E /* ScoreState.swift */; };
|
||||||
99F1D8A337EE46C8BDD34F60 /* BroadcastModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA97648294C4D98B3D85EFD /* BroadcastModels.swift */; };
|
6A26C9639E5342ACA259DB67 /* BroadcastModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9975D8D02CF4FA0A47696DD /* BroadcastModels.swift */; };
|
||||||
F024262D0D0F4B759E1A4F14 /* BroadcastOrientationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4A1042B44B41E0AE768E0C /* BroadcastOrientationPolicy.swift */; };
|
FF08A44E3B5C4C709095F08C /* BroadcastOrientationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2432C46DFBA4322887D8C59 /* BroadcastOrientationPolicy.swift */; };
|
||||||
FE9E0B76650246E490722317 /* BroadcastVideoOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97DF04B6B21743BC9615E634 /* BroadcastVideoOrientation.swift */; };
|
C3873D7719AA419AA0134B65 /* BroadcastVideoOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A43B670D8BE94F66B38885C8 /* BroadcastVideoOrientation.swift */; };
|
||||||
BD642A0BD19D424985FBF1A3 /* LiveBroadcastCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B031A4D51634E96BBD3D8DA /* LiveBroadcastCoordinator.swift */; };
|
56896861A77F4036B3763B59 /* LiveBroadcastCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F438E7E164F44C7B856C4808 /* LiveBroadcastCoordinator.swift */; };
|
||||||
B48421E7BD5D48E499948E2E /* LiveBroadcastEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC442280384D4194A66F25D2 /* LiveBroadcastEngine.swift */; };
|
E16207FC581A4182B171119C /* LiveBroadcastEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6D684B88BEB440F8D331D3D /* LiveBroadcastEngine.swift */; };
|
||||||
C6207D98BB484493BEDD4BBB /* CompactScoreboardElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF6E8429A9DF475E9C964A2A /* CompactScoreboardElement.swift */; };
|
1ABCBB3241B54AE3B8DC175F /* CompactScoreboardElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78104BD8D9044B659F33B02F /* CompactScoreboardElement.swift */; };
|
||||||
E715CA8C60E6439683E1DA0E /* OverlayCanvasRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA419130C5A248DCA3B4A016 /* OverlayCanvasRenderer.swift */; };
|
69707A2BF3574451AFE893F5 /* OverlayCanvasRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8048B96407947C7BA4222E8 /* OverlayCanvasRenderer.swift */; };
|
||||||
35F5E2E5FB0D4B9FA475ADA4 /* OverlayLogoCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF76F8D690C405D9FCC4B8E /* OverlayLogoCache.swift */; };
|
972B0F53517C4AC2A062FD68 /* OverlayLogoCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5BF3429BFBA4DB3BDBD721D /* OverlayLogoCache.swift */; };
|
||||||
6D8B0F1792E440C19F49AD03 /* OverlayMappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A1C8A803FB4CA1BA741E57 /* OverlayMappings.swift */; };
|
9455267569924A4485199B85 /* OverlayMappings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 509414F2274844F4B9A956C3 /* OverlayMappings.swift */; };
|
||||||
CC563D93928C438AB0B78E99 /* OverlayRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195EFB33D08D484489FD721B /* OverlayRenderer.swift */; };
|
FCBDDBB72AD142A39944DA39 /* OverlayRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59E96B1417004CD3BC247C0F /* OverlayRenderer.swift */; };
|
||||||
9343740F4EB94F609A4D1A51 /* OverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0DF408F60149008C9644C0 /* OverlayState.swift */; };
|
ABC5853FEC554FA4AFBDCD2E /* OverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DDC7305F3B549D0B7646B14 /* OverlayState.swift */; };
|
||||||
D71C1DFF234742DA81D23AF7 /* ScoreboardElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F0583912AA42F787751A7F /* ScoreboardElement.swift */; };
|
53A64EA59067426FA7BCEF2E /* ScoreboardElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D645FD397CD40DDA859F160 /* ScoreboardElement.swift */; };
|
||||||
DADD5004759C409F82D4FEE2 /* SponsorElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB19CB746D6146D9ABD1A1C4 /* SponsorElement.swift */; };
|
C4A9BD596C4A4ACD88F7557F /* SponsorElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B95E0D21B0407FA6723720 /* SponsorElement.swift */; };
|
||||||
957381C0C3A447E7A3240ACD /* WatermarkElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8C48EA12DB45FF978FA049 /* WatermarkElement.swift */; };
|
6AD0B3220B154EA2936C634A /* WatermarkElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31750F1B9E294337BDBD5B56 /* WatermarkElement.swift */; };
|
||||||
326AEF0FBFE74201BE70D2DD /* LivePreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 838A41F3BF1E42BDAA2CE2E6 /* LivePreviewView.swift */; };
|
713E0129656649FC8630FDC6 /* LivePreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46CE696CAB994E2C8E399776 /* LivePreviewView.swift */; };
|
||||||
DCC6F79099C641DF9EA6F36F /* StreamVideoPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2074992AD4E94430B9524FB3 /* StreamVideoPreset.swift */; };
|
451211FDF3214D2098798DB6 /* StreamVideoPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C2A2F7BAC2B4AC69E8BEAF7 /* StreamVideoPreset.swift */; };
|
||||||
CA82A2382C4A45BE88276507 /* BroadcastControlsOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51507FF41FB4B80831D70E3 /* BroadcastControlsOverlay.swift */; };
|
E5E21D088782469D8EB23543 /* AccountScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4419E10415414556B7C58458 /* AccountScreen.swift */; };
|
||||||
37E8D25C18014E0C8139D84D /* BroadcastScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EA7E4972BB74FDD884370D0 /* BroadcastScreen.swift */; };
|
5B51805239FA4D4D90919D86 /* BroadcastControlsOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = E860A0E35362427DA84F8972 /* BroadcastControlsOverlay.swift */; };
|
||||||
67A37D0BB28F4BD1872BACA6 /* LiveScoreActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2B124ACD024538B20863B8 /* LiveScoreActions.swift */; };
|
EE568EA02C404102B4DFD651 /* BroadcastScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71816F0D99E44551839474CE /* BroadcastScreen.swift */; };
|
||||||
7AA96446B33C4ECCB90DDFD0 /* MatchLiveWordmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B0AEBA3A0140D2BC9698DC /* MatchLiveWordmark.swift */; };
|
64EBCA992CD147BB8518DE60 /* LiveScoreActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4637B286559F4BC294018AC5 /* LiveScoreActions.swift */; };
|
||||||
599290557AE4430EA30582D7 /* MatchPrimaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84054AB3574CC5B8056694 /* MatchPrimaryButton.swift */; };
|
FE883346930E41C790474211 /* MatchLiveWordmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FF23D4B51AE4DA5B99D4021 /* MatchLiveWordmark.swift */; };
|
||||||
D71CB837FE844932AA590D30 /* MatchScreenScaffold.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7434175C1E849D7A8308896 /* MatchScreenScaffold.swift */; };
|
57EC4C4193D4412892219315 /* MatchPrimaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F04C9EAB5984F938EC60BF4 /* MatchPrimaryButton.swift */; };
|
||||||
52806453AD4C4E59BA2F05DE /* MatchSecondaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DE0F41386A741B2A6FC538B /* MatchSecondaryButton.swift */; };
|
C6A88BEC28824928A0F7ED08 /* MatchScreenScaffold.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F3C00B63534E6AA6D8A90A /* MatchScreenScaffold.swift */; };
|
||||||
FA601701F8684EE2BFDBBBFD /* MatchStatusBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6A499FE7D94EF498DA9A84 /* MatchStatusBadge.swift */; };
|
D74C538E4B754047B328E6F9 /* MatchSecondaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7403EB9DBD8459A93D9E2D8 /* MatchSecondaryButton.swift */; };
|
||||||
A85ED43E903E4983B1438D11 /* AccountScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13972C3F4664A89AE13D5D8 /* AccountScreen.swift */; };
|
0CB8933AC2B34D4099BBA881 /* MatchStatusBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BB2251A67E401A9F1E789E /* MatchStatusBadge.swift */; };
|
||||||
195AF301A0AC4BA58F8EDE95 /* ForgotPasswordScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF38B8E56394DEBA022F812 /* ForgotPasswordScreen.swift */; };
|
CA87B95E856947AC9304E423 /* ForgotPasswordScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8C38306C6F420DBC42DA2A /* ForgotPasswordScreen.swift */; };
|
||||||
8C0225C7F87A4F9A8A0C2919 /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA51BC65490E421AA3D16F02 /* LoginScreen.swift */; };
|
2C7E484A83584887A412E71E /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E124B3B49FC34520805CCC97 /* LoginScreen.swift */; };
|
||||||
7293CD3C1B634333A59FA782 /* MatchesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A439BB96CCB4C038EEF44DD /* MatchesScreen.swift */; };
|
E0352EDB139740DBB11DBD51 /* MatchesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A95962EF2A4B8F821343D9 /* MatchesScreen.swift */; };
|
||||||
465980490F2D417E87241EBA /* AppNavHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DD00428364442C6B8C55DDF /* AppNavHost.swift */; };
|
A2BB5F7A9BEA4F45AC9523C5 /* AppNavHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 866A83237E6943E89A165B9D /* AppNavHost.swift */; };
|
||||||
044E04EEE71D472EA524C555 /* ModalRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F958AB307244896BD8948D2 /* ModalRoutes.swift */; };
|
30CF022083914A188A9E30A0 /* ModalRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464CF87BEA644025B2D14644 /* ModalRoutes.swift */; };
|
||||||
52CEBF8B18834CB8B650FE16 /* Routes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C2A6AB0E164C8CBDF9CF7F /* Routes.swift */; };
|
BF6BFF14A642487CA8DE29C6 /* Routes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B214C9B30C794F00A31B0D83 /* Routes.swift */; };
|
||||||
94ADCCD464DD43149D0C0E60 /* BroadcastPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1702AF57020940DEBF0F9BA0 /* BroadcastPermissions.swift */; };
|
06FE9996B295456D8B8C7E96 /* BroadcastPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BFB2F18615747B1A1C9E9B2 /* BroadcastPermissions.swift */; };
|
||||||
F23C2967ED7140EB8DCB2D2A /* SplashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3004C07E608644AFB636C0C5 /* SplashScreen.swift */; };
|
142FA0805F1E40C69CAD3433 /* SplashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C29F5731A142C3A12B6DCA /* SplashScreen.swift */; };
|
||||||
47AD4ADC4ACE4F6DA7AD708C /* KeepScreenOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC39718A2EC74B078A0C5DE9 /* KeepScreenOn.swift */; };
|
B92A8F0A41CC4ECE8BFCE0D9 /* KeepScreenOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 004F86D8E8BE47E589B923FA /* KeepScreenOn.swift */; };
|
||||||
8B0A9A9DBAF346199EBA21B3 /* ScreenOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCEB22897600469E93762209 /* ScreenOrientation.swift */; };
|
1C4B54C40F4E4D1090A6BDA5 /* ScreenOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF10FF45004F41AD82397DC9 /* ScreenOrientation.swift */; };
|
||||||
D826E98233304F5FB27B27C3 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BC17CE70034FEE97707B21 /* ShareSheet.swift */; };
|
1A82C6F343F54284AFA8FECE /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B5C00419D09442FA8ED60F3 /* ShareSheet.swift */; };
|
||||||
579A3A8D49DF43E7B11942C6 /* MatchColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAAD219E4FA94CF885472711 /* MatchColors.swift */; };
|
7575030B9AEB4DEBAD986A23 /* MatchColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2996990D08341ABA52BE287 /* MatchColors.swift */; };
|
||||||
D0BEA6E726C04A95A8CC0018 /* StepMatchScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F84FF3F1E74E49A3EA5101 /* StepMatchScreen.swift */; };
|
777B73E69F8A4DC6A8E7C1DF /* StepMatchScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB037B1369B454D84F6850D /* StepMatchScreen.swift */; };
|
||||||
15DA64BB40B14C9B899A3729 /* StepNetworkTestScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1875AE0A77B94DF0921EE457 /* StepNetworkTestScreen.swift */; };
|
F67C0C88237F41DE8EDF6CB8 /* StepNetworkTestScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1079231B9A4E446AA9AD6C0A /* StepNetworkTestScreen.swift */; };
|
||||||
4DF6B21EFDD54DF999385511 /* StepTransmissionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3168221266004A33BA35042C /* StepTransmissionScreen.swift */; };
|
2B8E5D9945364094B74165DE /* StepTransmissionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC0179FE6BC4323B1F9E1D3 /* StepTransmissionScreen.swift */; };
|
||||||
AEF63662B6B5454F92986710 /* TeamBrandingEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97603C3A54342799CBD0C03 /* TeamBrandingEditor.swift */; };
|
45776A6A76D04EF5A0C0D187 /* TeamBrandingEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FBBE0F1399840FFA0E7EF2E /* TeamBrandingEditor.swift */; };
|
||||||
78179BA533074F1ABBB7391E /* TeamColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AFEAFB3E8F047B9A2B0DD04 /* TeamColorPicker.swift */; };
|
39F7D49D44244F51907E803D /* TeamColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7001BB5D65B34280B306ECCF /* TeamColorPicker.swift */; };
|
||||||
45E14846E79845CE9C20C5EC /* WizardComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7A5A0E6D9A49EA95918E79 /* WizardComponents.swift */; };
|
E417F20C78464CA78B28E3DE /* WizardComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B75DC6D0B2248B2A6C9AA66 /* WizardComponents.swift */; };
|
||||||
2049733B63794135A4BFBB53 /* WizardShellScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68CB1416AC24491CAA4CE87A /* WizardShellScreen.swift */; };
|
D1CF09F02F8844C4A22922F4 /* WizardShellScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3170F3149C614EC38B417905 /* WizardShellScreen.swift */; };
|
||||||
6B75AFC14BBF4E2B97762ECB /* ApiInstantTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73BB032A0DD74458B0E716C6 /* ApiInstantTests.swift */; };
|
ACC54AA19C5747CFA118C70B /* ApiInstantTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FEB862C3A34BF8AC24052E /* ApiInstantTests.swift */; };
|
||||||
9BA38C8D635F4770A232AE85 /* BroadcastOrientationPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C186E88B35A0443494AE6E8E /* BroadcastOrientationPolicyTests.swift */; };
|
592DF4BAC5624417A7123422 /* BroadcastOrientationPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5CA1FE59BA14F76BA94C995 /* BroadcastOrientationPolicyTests.swift */; };
|
||||||
1889CDB168794D81A5B24699 /* LiveBroadcastCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5751DB993C52460D960B8067 /* LiveBroadcastCoordinatorTests.swift */; };
|
C9174111ED4A42E887578BF0 /* LiveBroadcastCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1830F9A925334BA4B65D490E /* LiveBroadcastCoordinatorTests.swift */; };
|
||||||
E25CB4FB944141D0AAB57EDF /* LiveScoreDialogHostTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E243C00009048F6A778323C /* LiveScoreDialogHostTests.swift */; };
|
095654DAAF6C4EA4B73BAB61 /* LiveScoreDialogHostTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4F8BF2514BB4F5185827B95 /* LiveScoreDialogHostTests.swift */; };
|
||||||
6BE3B2533E6A4E3DA32EA972 /* MatchScoringRulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634AD5C2E53B4C098582284A /* MatchScoringRulesTests.swift */; };
|
AA18DECE8D08461B9197EB71 /* MatchScoringRulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8964CE287E2C4C2DB701497B /* MatchScoringRulesTests.swift */; };
|
||||||
B88859D9B34E4F289913DDFC /* ScoreActionDecodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DE055717014393B3F62D5A /* ScoreActionDecodeTests.swift */; };
|
5D91C53D2E8A4952937F816B /* ScoreActionDecodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10AD0F18190542818572CAEF /* ScoreActionDecodeTests.swift */; };
|
||||||
B8CC446DB3AE4BABB4D739D1 /* ScoreControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C1AC6562ED4A908D7C8B0A /* ScoreControllerTests.swift */; };
|
FB66DD0422E14C54AC5B3EDB /* ScoreControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF142EBF33B45739BA8E42C /* ScoreControllerTests.swift */; };
|
||||||
6CCB67439127403180D9C697 /* ThermalAdaptationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 610A4D03FA384F0287AAF825 /* ThermalAdaptationTests.swift */; };
|
AB6FF1A930EB459091B77922 /* ThermalAdaptationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377A2D2B2DA440AFB0CE2298 /* ThermalAdaptationTests.swift */; };
|
||||||
C44DD19CDB6545A381B61D20 /* Assets in Resources */ = {isa = PBXBuildFile; fileRef = F68654552B254000B6F0BE97; };
|
30D3EC3BE61744868019114F /* Assets in Resources */ = {isa = PBXBuildFile; fileRef = 2146FBAC1D7F4FF7B47D360F; };
|
||||||
7C8A2DFFAB6B4CB8AA3E4FE8 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 6DFD25C0855F482DBEFD8757; };
|
AA3A68B2C1784294ADB89605 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 857C036B5B5C43368506DD8B; };
|
||||||
8D479F8873F94073938D737E /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 12C3FA28B28146B9A8E3A70A; };
|
6D6C2C09593B4EADBF082FB5 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 3A6F9AAB5A1249BBB4FC02E6; };
|
||||||
9A894DBC632C4904BC5D9A78 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5D760AAFB9C34DACBFC2387A; };
|
4F520F571EC647CB9A7B5465 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 30B07E7585A7408EA47C8633; };
|
||||||
9246A8532B66443A83535192 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 85B0F928887C44128434974E; };
|
8C8FEABCD83C422BA5A5DEA3 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EEFE07D4B6FD44199A5B9C25; };
|
||||||
5DA941A5928A4F638223030C /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = E907C350C3E5410FB4A2038D; };
|
4AE99343B3A442D6AEBF7032 /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2ACAF5B8A617427C8CBF56AD; };
|
||||||
B6A69164398F4F9FB84EC475 = {isa = PBXGroup; children = (86BA4622CE11450BAD7902B9, E068E1D4709041789B1E8F5A, 2165E0C34A8B43F28AC2B21C); sourceTree = "<group>"; };
|
7E992B84100649D8BE8507F7 = {isa = PBXGroup; children = (DDEF729FE3334F8998C4A31C, 6987D3982FAD44A6869B9FD6, 0ADC6126267C410F9B60B426); sourceTree = "<group>"; };
|
||||||
86BA4622CE11450BAD7902B9 = {isa = PBXGroup; children = (4FC590728C2F47DE94AEADA3, 69F95F7CAF894139BA244AFF, 5E30D25B02704FAE9C0A4040, A59093CB86BB41FE9DF37182, C00F6C82C9A04A50B1D34BA3, 6F83B04D0BC84879A07C9BFE, 33DEE4675BAB413E9F69549B, 14FE2B5F844A482C91245755, AA9DF2F1C5F04EA198286266, 8EEFEB75DDB04C4986774D4B, C84694361A004982B4007CA5, 1AD71EE7F4A54818A6C427C9, 610902FBCEB7478286C88C08, DD9687B43B5840DD96FAD1C9, 905A6416560A4442AA7D2FCF, 9299E98557E04C5F8DC736F8, 49E1D454901048A58DCE7C41, A90696A40A584C5794938FDA, 2C3F8293D48D44A6A569F452, 347DADA50AE44484ABF19903, 69794703A6D74DB9AA3D16A2, D274E6DA2B7B47C9822FB517, E4BAEE4AB7834E19BA57C4A1, 1060DB32269548BE895EFA7F, CA265A4F2CAA41DA8F68A35C, 0381775B0B1D4378A8BF289A, 85D4CBF80A8F447790235E7C, 2EA97648294C4D98B3D85EFD, FA4A1042B44B41E0AE768E0C, 97DF04B6B21743BC9615E634, 1B031A4D51634E96BBD3D8DA, BC442280384D4194A66F25D2, EF6E8429A9DF475E9C964A2A, AA419130C5A248DCA3B4A016, 8CF76F8D690C405D9FCC4B8E, E1A1C8A803FB4CA1BA741E57, 195EFB33D08D484489FD721B, DB0DF408F60149008C9644C0, E9F0583912AA42F787751A7F, FB19CB746D6146D9ABD1A1C4, CD8C48EA12DB45FF978FA049, 838A41F3BF1E42BDAA2CE2E6, 2074992AD4E94430B9524FB3, B51507FF41FB4B80831D70E3, 8EA7E4972BB74FDD884370D0, CC2B124ACD024538B20863B8, 31B0AEBA3A0140D2BC9698DC, 0C84054AB3574CC5B8056694, D7434175C1E849D7A8308896, 3DE0F41386A741B2A6FC538B, 1F6A499FE7D94EF498DA9A84, E13972C3F4664A89AE13D5D8, DDF38B8E56394DEBA022F812, DA51BC65490E421AA3D16F02, 0A439BB96CCB4C038EEF44DD, 5DD00428364442C6B8C55DDF, 9F958AB307244896BD8948D2, 21C2A6AB0E164C8CBDF9CF7F, 1702AF57020940DEBF0F9BA0, 3004C07E608644AFB636C0C5, DC39718A2EC74B078A0C5DE9, BCEB22897600469E93762209, 13BC17CE70034FEE97707B21, AAAD219E4FA94CF885472711, 29F84FF3F1E74E49A3EA5101, 1875AE0A77B94DF0921EE457, 3168221266004A33BA35042C, C97603C3A54342799CBD0C03, 5AFEAFB3E8F047B9A2B0DD04, CE7A5A0E6D9A49EA95918E79, 68CB1416AC24491CAA4CE87A, F68654552B254000B6F0BE97, 1255FF9134D246ECBE1DF72C, 6DFD25C0855F482DBEFD8757, 12C3FA28B28146B9A8E3A70A, 5D760AAFB9C34DACBFC2387A, 85B0F928887C44128434974E, E907C350C3E5410FB4A2038D); name = MatchLiveTv; sourceTree = "<group>"; };
|
DDEF729FE3334F8998C4A31C = {isa = PBXGroup; children = (5F5FC005B683447B82372E36, C7D22FF2CF3D4230A7BAA60C, 9F180A1FA5DD4DB3BA7E3B41, 123A61DD4A6442728811488E, CDDF270D449A43F18399966D, 902831E3D87C46359F0D0A21, ADBBD9C8DF9F4A47ACEFE7B1, AAC2A198868F4B4E9010F862, C9D84DE8EFA34B4CBDFF43F1, 31251A1297F24C70A14D8702, 1BEBDFA6B21041729156ADFA, 17E7568BD3D94B34A361F470, 99D52E8096064A359AAE3D47, 7FC98372F1BD474BB0365488, 98526C26B2584F55AADF0FFF, 50C70C614F3C45B9B824E465, EE0A49E8D59947448DAA7851, 537FC2C063D341DF97A391B9, 813463F3E17D453EAA801739, CCC8ECFD24A14054BDD984C3, 87C01CC031C34343B3EBFF08, B0B243B2A21344558626DF7F, 81CA0BDC6EE44C4290D7E483, 951A7265EF5C41A9A12DD86A, 18445F0E4070424F86D55556, 61FCDE0B00FB485CB9B09110, EA08E23008964D02AB59377E, C9975D8D02CF4FA0A47696DD, B2432C46DFBA4322887D8C59, A43B670D8BE94F66B38885C8, F438E7E164F44C7B856C4808, C6D684B88BEB440F8D331D3D, 78104BD8D9044B659F33B02F, A8048B96407947C7BA4222E8, B5BF3429BFBA4DB3BDBD721D, 509414F2274844F4B9A956C3, 59E96B1417004CD3BC247C0F, 2DDC7305F3B549D0B7646B14, 9D645FD397CD40DDA859F160, 18B95E0D21B0407FA6723720, 31750F1B9E294337BDBD5B56, 46CE696CAB994E2C8E399776, 8C2A2F7BAC2B4AC69E8BEAF7, 4419E10415414556B7C58458, E860A0E35362427DA84F8972, 71816F0D99E44551839474CE, 4637B286559F4BC294018AC5, 2FF23D4B51AE4DA5B99D4021, 6F04C9EAB5984F938EC60BF4, 39F3C00B63534E6AA6D8A90A, C7403EB9DBD8459A93D9E2D8, 34BB2251A67E401A9F1E789E, AF8C38306C6F420DBC42DA2A, E124B3B49FC34520805CCC97, 56A95962EF2A4B8F821343D9, 866A83237E6943E89A165B9D, 464CF87BEA644025B2D14644, B214C9B30C794F00A31B0D83, 3BFB2F18615747B1A1C9E9B2, D7C29F5731A142C3A12B6DCA, 004F86D8E8BE47E589B923FA, FF10FF45004F41AD82397DC9, 2B5C00419D09442FA8ED60F3, D2996990D08341ABA52BE287, EAB037B1369B454D84F6850D, 1079231B9A4E446AA9AD6C0A, 7EC0179FE6BC4323B1F9E1D3, 6FBBE0F1399840FFA0E7EF2E, 7001BB5D65B34280B306ECCF, 5B75DC6D0B2248B2A6C9AA66, 3170F3149C614EC38B417905, 2146FBAC1D7F4FF7B47D360F, 8588711837244B19B84BA0B3, 857C036B5B5C43368506DD8B, 3A6F9AAB5A1249BBB4FC02E6, 30B07E7585A7408EA47C8633, EEFE07D4B6FD44199A5B9C25, 2ACAF5B8A617427C8CBF56AD); name = MatchLiveTv; sourceTree = "<group>"; };
|
||||||
E068E1D4709041789B1E8F5A = {isa = PBXGroup; children = (73BB032A0DD74458B0E716C6, C186E88B35A0443494AE6E8E, 5751DB993C52460D960B8067, 0E243C00009048F6A778323C, 634AD5C2E53B4C098582284A, B7DE055717014393B3F62D5A, C3C1AC6562ED4A908D7C8B0A, 610A4D03FA384F0287AAF825); name = MatchLiveTvTests; sourceTree = "<group>"; };
|
6987D3982FAD44A6869B9FD6 = {isa = PBXGroup; children = (75FEB862C3A34BF8AC24052E, E5CA1FE59BA14F76BA94C995, 1830F9A925334BA4B65D490E, F4F8BF2514BB4F5185827B95, 8964CE287E2C4C2DB701497B, 10AD0F18190542818572CAEF, 6DF142EBF33B45739BA8E42C, 377A2D2B2DA440AFB0CE2298); name = MatchLiveTvTests; sourceTree = "<group>"; };
|
||||||
2165E0C34A8B43F28AC2B21C = {isa = PBXGroup; children = (6FF24BB96E9C40F6A9F6E25A, 8F679C9C03AE47D6A028DBAC); name = Products; sourceTree = "<group>"; };
|
0ADC6126267C410F9B60B426 = {isa = PBXGroup; children = (CE0F9D7D5EE749E8AAE6AB43, 3FC0CC8155BE469ABB420DC5); name = Products; sourceTree = "<group>"; };
|
||||||
3B35A518C56047A48825F0F8 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (F7624153A1C84C218B602FFB, D973F2B503854C6AA61A1559, FE2D8C8359CC4DA189DF5DC6, B607A146AE754F6A819FB186, B0D93B493FD0427CA72F5862, 3C223B19BA2149C5B7E5CC5A, 3D119DE97DE5452D903F364C, 8ABF00BDC15C400A9089FC28, 7D2649B9131F4DDA83F68B72, AB71730B7CA24D3E8667BCFF, ADA58448C2344DADAA90F212, 95F7871858C44379A62012BA, 3FBBEF8DFF5E4F5D9E34C860, 91694276C76B438F8B52448F, 51D849AFAC8D4F57BEF05CAB, D771BABE58A3439CA1768F7F, 23C149E317BD416D9CF0B171, 43C57FF23CB347AC99284468, 8661E674C82545C4AEC0A7CE, E133D004CF0A4FF7A51A47B1, 72090ACA64CB4885BE7AB333, D80261301CA740568D8807D2, 9ECD8B486DF84890BD39B108, C217B8AD49D04976A6D7FC7E, 978AAF829F654537AC473F52, 032C790773A848B7A0434C67, A37BC192D6C9433F83FABAA8, 99F1D8A337EE46C8BDD34F60, F024262D0D0F4B759E1A4F14, FE9E0B76650246E490722317, BD642A0BD19D424985FBF1A3, B48421E7BD5D48E499948E2E, C6207D98BB484493BEDD4BBB, E715CA8C60E6439683E1DA0E, 35F5E2E5FB0D4B9FA475ADA4, 6D8B0F1792E440C19F49AD03, CC563D93928C438AB0B78E99, 9343740F4EB94F609A4D1A51, D71C1DFF234742DA81D23AF7, DADD5004759C409F82D4FEE2, 957381C0C3A447E7A3240ACD, 326AEF0FBFE74201BE70D2DD, DCC6F79099C641DF9EA6F36F, CA82A2382C4A45BE88276507, 37E8D25C18014E0C8139D84D, 67A37D0BB28F4BD1872BACA6, 7AA96446B33C4ECCB90DDFD0, 599290557AE4430EA30582D7, D71CB837FE844932AA590D30, 52806453AD4C4E59BA2F05DE, FA601701F8684EE2BFDBBBFD, A85ED43E903E4983B1438D11, 195AF301A0AC4BA58F8EDE95, 8C0225C7F87A4F9A8A0C2919, 7293CD3C1B634333A59FA782, 465980490F2D417E87241EBA, 044E04EEE71D472EA524C555, 52CEBF8B18834CB8B650FE16, 94ADCCD464DD43149D0C0E60, F23C2967ED7140EB8DCB2D2A, 47AD4ADC4ACE4F6DA7AD708C, 8B0A9A9DBAF346199EBA21B3, D826E98233304F5FB27B27C3, 579A3A8D49DF43E7B11942C6, D0BEA6E726C04A95A8CC0018, 15DA64BB40B14C9B899A3729, 4DF6B21EFDD54DF999385511, AEF63662B6B5454F92986710, 78179BA533074F1ABBB7391E, 45E14846E79845CE9C20C5EC, 2049733B63794135A4BFBB53); runOnlyForDeploymentPostprocessing = 0; };
|
3E146F1019B842318E38BF4D = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (65D33C32CF91408B91AFF5D4, F4C4427723C34532AFA1F798, E75C942B73594F1484927866, 38BACC0DAAA147EB8955A60C, 99B3D05A3D704DA1A513689F, 65EB1857F331469BAC9A18D7, 2F393B5FCD244E65B13C97A3, 5620C77D9A5B47F3BA0741E4, D75CBE430CF947B1B8B0225B, A74ACBA3E07740E59502306F, AA18CC40AAB249ECB8C88B85, 162DC182A26243599EEA862A, 2A0825BF1DCC4DC2B1FBC236, 70D5E80900C14B0897F02BF8, 9391C9EA0B834DC8956483DF, 359A4FD093C84543AD4DA3B1, 59B045E87F2946B8BC8EA65A, AECC36D80A0C411AB47D581A, 39335ED5DE5847E5904222AB, 470957DE79A84D9889F0663C, 66815B27A71244F791DE3C2F, 244F331A033D4A32A0DC46CB, 6EB9973427144A28B857B49E, 454725D14B224276B06BCC67, C19C5E8152C44669AE5D8874, 20A6FAB1CB7F47C085B75A22, 8723E1F8443A46B3AF49E8A3, 6A26C9639E5342ACA259DB67, FF08A44E3B5C4C709095F08C, C3873D7719AA419AA0134B65, 56896861A77F4036B3763B59, E16207FC581A4182B171119C, 1ABCBB3241B54AE3B8DC175F, 69707A2BF3574451AFE893F5, 972B0F53517C4AC2A062FD68, 9455267569924A4485199B85, FCBDDBB72AD142A39944DA39, ABC5853FEC554FA4AFBDCD2E, 53A64EA59067426FA7BCEF2E, C4A9BD596C4A4ACD88F7557F, 6AD0B3220B154EA2936C634A, 713E0129656649FC8630FDC6, 451211FDF3214D2098798DB6, E5E21D088782469D8EB23543, 5B51805239FA4D4D90919D86, EE568EA02C404102B4DFD651, 64EBCA992CD147BB8518DE60, FE883346930E41C790474211, 57EC4C4193D4412892219315, C6A88BEC28824928A0F7ED08, D74C538E4B754047B328E6F9, 0CB8933AC2B34D4099BBA881, CA87B95E856947AC9304E423, 2C7E484A83584887A412E71E, E0352EDB139740DBB11DBD51, A2BB5F7A9BEA4F45AC9523C5, 30CF022083914A188A9E30A0, BF6BFF14A642487CA8DE29C6, 06FE9996B295456D8B8C7E96, 142FA0805F1E40C69CAD3433, B92A8F0A41CC4ECE8BFCE0D9, 1C4B54C40F4E4D1090A6BDA5, 1A82C6F343F54284AFA8FECE, 7575030B9AEB4DEBAD986A23, 777B73E69F8A4DC6A8E7C1DF, F67C0C88237F41DE8EDF6CB8, 2B8E5D9945364094B74165DE, 45776A6A76D04EF5A0C0D187, 39F7D49D44244F51907E803D, E417F20C78464CA78B28E3DE, D1CF09F02F8844C4A22922F4); runOnlyForDeploymentPostprocessing = 0; };
|
||||||
729C230D5EB64A76BCD517B4 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (6B75AFC14BBF4E2B97762ECB, 9BA38C8D635F4770A232AE85, 1889CDB168794D81A5B24699, E25CB4FB944141D0AAB57EDF, 6BE3B2533E6A4E3DA32EA972, B88859D9B34E4F289913DDFC, B8CC446DB3AE4BABB4D739D1, 6CCB67439127403180D9C697); runOnlyForDeploymentPostprocessing = 0; };
|
FA890E18B4EB44C58C124F5C = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (ACC54AA19C5747CFA118C70B, 592DF4BAC5624417A7123422, C9174111ED4A42E887578BF0, 095654DAAF6C4EA4B73BAB61, AA18DECE8D08461B9197EB71, 5D91C53D2E8A4952937F816B, FB66DD0422E14C54AC5B3EDB, AB6FF1A930EB459091B77922); runOnlyForDeploymentPostprocessing = 0; };
|
||||||
6B4D5383389142E7AE9C4F41 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (C44DD19CDB6545A381B61D20, 7C8A2DFFAB6B4CB8AA3E4FE8, 8D479F8873F94073938D737E, 9A894DBC632C4904BC5D9A78, 9246A8532B66443A83535192, 5DA941A5928A4F638223030C); runOnlyForDeploymentPostprocessing = 0; };
|
B75DDD49798641E58FBE57D0 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (30D3EC3BE61744868019114F, AA3A68B2C1784294ADB89605, 6D6C2C09593B4EADBF082FB5, 4F520F571EC647CB9A7B5465, 8C8FEABCD83C422BA5A5DEA3, 4AE99343B3A442D6AEBF7032); runOnlyForDeploymentPostprocessing = 0; };
|
||||||
AA7CFC56BCC040A4AB487E2C = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
|
414C9A6F8BE0437593A403A9 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
|
||||||
6E9DDC30CE734AC1AB90CC24 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
|
C16D70862B15401AA91E067A = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
|
||||||
D3DDF0C54D1744C09B415888 = {isa = XCBuildConfiguration; buildSettings = {
|
ABC7AFD6F8DE449D90C8AD6A = {isa = XCBuildConfiguration; buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = NO;
|
GENERATE_INFOPLIST_FILE = NO;
|
||||||
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
@@ -202,7 +202,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
API_BASE_URL = "https://www.matchlivetv.it";
|
API_BASE_URL = "https://www.matchlivetv.it";
|
||||||
@@ -211,10 +211,10 @@
|
|||||||
|
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
}; name = Debug; };
|
}; name = Debug; };
|
||||||
974D195BCA9F41ECA825E63D = {isa = XCBuildConfiguration; buildSettings = {
|
71636134BDC0490291EAAE3E = {isa = XCBuildConfiguration; buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = NO;
|
GENERATE_INFOPLIST_FILE = NO;
|
||||||
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
@@ -225,20 +225,20 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
API_BASE_URL = "https://www.matchlivetv.it";
|
API_BASE_URL = "https://www.matchlivetv.it";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
}; name = Release; };
|
}; name = Release; };
|
||||||
BD9014D2E1B34341B2930049 = {isa = XCBuildConfiguration; buildSettings = {
|
EFB6F8A078FC44639CBDACBD = {isa = XCBuildConfiguration; buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -246,13 +246,13 @@
|
|||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatchLiveTv.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MatchLiveTv";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatchLiveTv.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MatchLiveTv";
|
||||||
}; name = Debug; };
|
}; name = Debug; };
|
||||||
F613BB5D3D6744F3BD58BCBB = {isa = XCBuildConfiguration; buildSettings = {
|
6482CB0453A5481CBE8BA182 = {isa = XCBuildConfiguration; buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -260,17 +260,17 @@
|
|||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatchLiveTv.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MatchLiveTv";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MatchLiveTv.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MatchLiveTv";
|
||||||
}; name = Release; };
|
}; name = Release; };
|
||||||
E2D337A0090F45C3BD12CEA4 = {isa = XCBuildConfiguration; buildSettings = {IPHONEOS_DEPLOYMENT_TARGET = 16.0; SWIFT_VERSION = 5.0; }; name = Debug; };
|
19E8D060E51148A4B9C398B0 = {isa = XCBuildConfiguration; buildSettings = {IPHONEOS_DEPLOYMENT_TARGET = 16.0; SWIFT_VERSION = 5.0; }; name = Debug; };
|
||||||
DF036DDA33454934B5DBA96F = {isa = XCBuildConfiguration; buildSettings = {IPHONEOS_DEPLOYMENT_TARGET = 16.0; SWIFT_VERSION = 5.0; }; name = Release; };
|
61160469A90147FA9D4C7CA9 = {isa = XCBuildConfiguration; buildSettings = {IPHONEOS_DEPLOYMENT_TARGET = 16.0; SWIFT_VERSION = 5.0; }; name = Release; };
|
||||||
51779CE259A14053B83F1D94 = {isa = XCConfigurationList; buildConfigurations = (D3DDF0C54D1744C09B415888, 974D195BCA9F41ECA825E63D); defaultConfigurationName = Release; };
|
117DCD84E04B4B03A2BFFFEA = {isa = XCConfigurationList; buildConfigurations = (ABC7AFD6F8DE449D90C8AD6A, 71636134BDC0490291EAAE3E); defaultConfigurationName = Release; };
|
||||||
70CF9007D5E9469CB989FABF = {isa = XCConfigurationList; buildConfigurations = (BD9014D2E1B34341B2930049, F613BB5D3D6744F3BD58BCBB); defaultConfigurationName = Release; };
|
FE6CC95B39C044E1AC614098 = {isa = XCConfigurationList; buildConfigurations = (EFB6F8A078FC44639CBDACBD, 6482CB0453A5481CBE8BA182); defaultConfigurationName = Release; };
|
||||||
86E5AF075085439BA443DBA7 = {isa = XCConfigurationList; buildConfigurations = (E2D337A0090F45C3BD12CEA4, DF036DDA33454934B5DBA96F); defaultConfigurationName = Release; };
|
EDC625652E214655BDA2B2AC = {isa = XCConfigurationList; buildConfigurations = (19E8D060E51148A4B9C398B0, 61160469A90147FA9D4C7CA9); defaultConfigurationName = Release; };
|
||||||
768EC47B451F4731A05BE1F9 = {isa = PBXNativeTarget; buildConfigurationList = 51779CE259A14053B83F1D94; buildPhases = (3B35A518C56047A48825F0F8, AA7CFC56BCC040A4AB487E2C, 6B4D5383389142E7AE9C4F41); buildRules = (); dependencies = (); name = MatchLiveTv; packageProductDependencies = (31418599149E4F7684EABE04, 1712041BB26748D78A1D8F49); productName = MatchLiveTv; productReference = 6FF24BB96E9C40F6A9F6E25A; productType = "com.apple.product-type.application"; };
|
F54F6C97361C4E8A96AEDD11 = {isa = PBXNativeTarget; buildConfigurationList = 117DCD84E04B4B03A2BFFFEA; buildPhases = (3E146F1019B842318E38BF4D, 414C9A6F8BE0437593A403A9, B75DDD49798641E58FBE57D0); buildRules = (); dependencies = (); name = MatchLiveTv; packageProductDependencies = (74B2BB60EC504F4E9CAFDDC8, 8D1C04B6B7DF4271AC84A016); productName = MatchLiveTv; productReference = CE0F9D7D5EE749E8AAE6AB43; productType = "com.apple.product-type.application"; };
|
||||||
057F8600A1DB4A8DB4A46300 = {isa = PBXContainerItemProxy; containerPortal = 1906C5F192A44C6284A9FC4C /* Project object */; proxyType = 1; remoteGlobalIDString = 768EC47B451F4731A05BE1F9; remoteInfo = MatchLiveTv; };
|
58E3C5EC752E497FBFD32D78 = {isa = PBXContainerItemProxy; containerPortal = AE0076753A1840A19E9F565F /* Project object */; proxyType = 1; remoteGlobalIDString = F54F6C97361C4E8A96AEDD11; remoteInfo = MatchLiveTv; };
|
||||||
56E58DFB903041BB95600D33 = {isa = PBXTargetDependency; target = 768EC47B451F4731A05BE1F9 /* MatchLiveTv */; targetProxy = 057F8600A1DB4A8DB4A46300 /* PBXContainerItemProxy */; };
|
E2FB115E6BB84F2EA8EA369B = {isa = PBXTargetDependency; target = F54F6C97361C4E8A96AEDD11 /* MatchLiveTv */; targetProxy = 58E3C5EC752E497FBFD32D78 /* PBXContainerItemProxy */; };
|
||||||
F6079500E62048DB89AE3866 = {isa = PBXNativeTarget; buildConfigurationList = 70CF9007D5E9469CB989FABF; buildPhases = (729C230D5EB64A76BCD517B4, 6E9DDC30CE734AC1AB90CC24); buildRules = (); dependencies = (56E58DFB903041BB95600D33); name = MatchLiveTvTests; productName = MatchLiveTvTests; productReference = 8F679C9C03AE47D6A028DBAC; productType = "com.apple.product-type.bundle.unit-test"; };
|
20C695DBFB4042879308B0F5 = {isa = PBXNativeTarget; buildConfigurationList = FE6CC95B39C044E1AC614098; buildPhases = (FA890E18B4EB44C58C124F5C, C16D70862B15401AA91E067A); buildRules = (); dependencies = (E2FB115E6BB84F2EA8EA369B); name = MatchLiveTvTests; productName = MatchLiveTvTests; productReference = 3FC0CC8155BE469ABB420DC5; productType = "com.apple.product-type.bundle.unit-test"; };
|
||||||
4901BAD7A32F4CFD805083BE = {isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/shogo4405/HaishinKit.swift"; requirement = {kind = upToNextMajorVersion; minimumVersion = 2.0.0;}; };
|
294A8F0AC0E54F1EB302705C = {isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/shogo4405/HaishinKit.swift"; requirement = {kind = upToNextMajorVersion; minimumVersion = 2.0.0;}; };
|
||||||
1906C5F192A44C6284A9FC4C = {isa = PBXProject; attributes = {BuildIndependentTargetsInParallel = 0; LastSwiftUpdateCheck = 1600;}; buildConfigurationList = 86E5AF075085439BA443DBA7; compatibilityVersion = "Xcode 15.0"; developmentRegion = it; mainGroup = B6A69164398F4F9FB84EC475; packageReferences = (4901BAD7A32F4CFD805083BE); productRefGroup = 2165E0C34A8B43F28AC2B21C; targets = (768EC47B451F4731A05BE1F9, F6079500E62048DB89AE3866); };
|
AE0076753A1840A19E9F565F = {isa = PBXProject; attributes = {BuildIndependentTargetsInParallel = 0; LastSwiftUpdateCheck = 1600;}; buildConfigurationList = EDC625652E214655BDA2B2AC; compatibilityVersion = "Xcode 15.0"; developmentRegion = it; mainGroup = 7E992B84100649D8BE8507F7; packageReferences = (294A8F0AC0E54F1EB302705C); productRefGroup = 0ADC6126267C410F9B60B426; targets = (F54F6C97361C4E8A96AEDD11, 20C695DBFB4042879308B0F5); };
|
||||||
};
|
};
|
||||||
rootObject = 1906C5F192A44C6284A9FC4C /* Project object */;
|
rootObject = AE0076753A1840A19E9F565F /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,28 +3,28 @@
|
|||||||
<BuildAction parallelizeBuildables="YES" buildImplicitDependencies="YES">
|
<BuildAction parallelizeBuildables="YES" buildImplicitDependencies="YES">
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry buildForTesting="YES" buildForRunning="YES" buildForProfiling="YES" buildForArchiving="YES" buildForAnalyzing="YES">
|
<BuildActionEntry buildForTesting="YES" buildForRunning="YES" buildForProfiling="YES" buildForArchiving="YES" buildForAnalyzing="YES">
|
||||||
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="768EC47B451F4731A05BE1F9" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="F54F6C97361C4E8A96AEDD11" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
<BuildActionEntry buildForTesting="YES" buildForRunning="NO" buildForProfiling="NO" buildForArchiving="NO" buildForAnalyzing="NO">
|
<BuildActionEntry buildForTesting="YES" buildForRunning="NO" buildForProfiling="NO" buildForArchiving="NO" buildForAnalyzing="NO">
|
||||||
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="F6079500E62048DB89AE3866" BuildableName="MatchLiveTvTests.xctest" BlueprintName="MatchLiveTvTests" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="20C695DBFB4042879308B0F5" BuildableName="MatchLiveTvTests.xctest" BlueprintName="MatchLiveTvTests" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction buildConfiguration="Debug" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv="YES">
|
<TestAction buildConfiguration="Debug" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv="YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
<TestableReference skipped="NO">
|
<TestableReference skipped="NO">
|
||||||
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="F6079500E62048DB89AE3866" BuildableName="MatchLiveTvTests.xctest" BlueprintName="MatchLiveTvTests" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="20C695DBFB4042879308B0F5" BuildableName="MatchLiveTvTests.xctest" BlueprintName="MatchLiveTvTests" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction buildConfiguration="Debug" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" useCustomWorkingDirectory="NO" ignoresPersistentStateOnLaunch="NO" debugDocumentVersioning="YES" debugServiceExtension="internal" allowLocationSimulation="YES">
|
<LaunchAction buildConfiguration="Debug" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" useCustomWorkingDirectory="NO" ignoresPersistentStateOnLaunch="NO" debugDocumentVersioning="YES" debugServiceExtension="internal" allowLocationSimulation="YES">
|
||||||
<BuildableProductRunnable runnableDebuggingMode="0">
|
<BuildableProductRunnable runnableDebuggingMode="0">
|
||||||
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="768EC47B451F4731A05BE1F9" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="F54F6C97361C4E8A96AEDD11" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction buildConfiguration="Release" shouldUseLaunchSchemeArgsEnv="YES" savedToolIdentifier="" useCustomWorkingDirectory="NO" debugDocumentVersioning="YES">
|
<ProfileAction buildConfiguration="Release" shouldUseLaunchSchemeArgsEnv="YES" savedToolIdentifier="" useCustomWorkingDirectory="NO" debugDocumentVersioning="YES">
|
||||||
<BuildableProductRunnable runnableDebuggingMode="0">
|
<BuildableProductRunnable runnableDebuggingMode="0">
|
||||||
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="768EC47B451F4731A05BE1F9" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
<BuildableReference BuildableIdentifier="primary" BlueprintIdentifier="F54F6C97361C4E8A96AEDD11" BuildableName="MatchLiveTv.app" BlueprintName="MatchLiveTv" ReferencedContainer="container:MatchLiveTv.xcodeproj"/>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
<AnalyzeAction buildConfiguration="Debug"/>
|
<AnalyzeAction buildConfiguration="Debug"/>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ enum L10n {
|
|||||||
"account.confirm.password": "Conferma password",
|
"account.confirm.password": "Conferma password",
|
||||||
"account.current.password": "Password attuale",
|
"account.current.password": "Password attuale",
|
||||||
"account.name.label": "Nome",
|
"account.name.label": "Nome",
|
||||||
"account.new.password": "Nuova password (min. 8 caratteri)",
|
"account.new.password": "Nuova password (min. 8, almeno 3 tipi di caratteri)",
|
||||||
"account.password.heading": "Cambia password",
|
"account.password.heading": "Cambia password",
|
||||||
"account.password.saved": "Password aggiornata",
|
"account.password.saved": "Password aggiornata",
|
||||||
"account.profile.heading": "Profilo",
|
"account.profile.heading": "Profilo",
|
||||||
@@ -194,7 +194,7 @@ enum L10n {
|
|||||||
"match.status.start": "AVVIA",
|
"match.status.start": "AVVIA",
|
||||||
"matches.active.team": "Squadra attiva: %1$@.",
|
"matches.active.team": "Squadra attiva: %1$@.",
|
||||||
"matches.change": "Cambia",
|
"matches.change": "Cambia",
|
||||||
"matches.empty.hint": "Programma una partita o avviane una nuova con «Nuova partita».",
|
"matches.empty.hint": "Tocca «Nuova partita» per programmare in anticipo o avviare subito.",
|
||||||
"matches.empty.title": "Nessuna partita in calendario",
|
"matches.empty.title": "Nessuna partita in calendario",
|
||||||
"matches.hello": "Ciao, %1$@",
|
"matches.hello": "Ciao, %1$@",
|
||||||
"matches.load.error": "Errore caricamento",
|
"matches.load.error": "Errore caricamento",
|
||||||
@@ -212,9 +212,8 @@ enum L10n {
|
|||||||
"matches.no.team.title": "Nessuna squadra assegnata",
|
"matches.no.team.title": "Nessuna squadra assegnata",
|
||||||
"matches.ready.title": "Pronte da avviare",
|
"matches.ready.title": "Pronte da avviare",
|
||||||
"matches.retry": "Riprova",
|
"matches.retry": "Riprova",
|
||||||
"matches.schedule": "Partita programmata",
|
|
||||||
"matches.scheduled.title": "Partite programmate",
|
"matches.scheduled.title": "Partite programmate",
|
||||||
"matches.subtitle": "Riprendi una diretta in corso o avvia una partita programmata.",
|
"matches.subtitle": "Riprendi una diretta in corso o avvia una nuova partita.",
|
||||||
"matches.tap.change.team": "Tocca per cambiare squadra",
|
"matches.tap.change.team": "Tocca per cambiare squadra",
|
||||||
"matches.team.for.live": "Squadra per la diretta",
|
"matches.team.for.live": "Squadra per la diretta",
|
||||||
"matches.title": "Partite",
|
"matches.title": "Partite",
|
||||||
@@ -372,7 +371,7 @@ enum L10n {
|
|||||||
"account.confirm.password": "Confirm password",
|
"account.confirm.password": "Confirm password",
|
||||||
"account.current.password": "Current password",
|
"account.current.password": "Current password",
|
||||||
"account.name.label": "Name",
|
"account.name.label": "Name",
|
||||||
"account.new.password": "New password (min. 8 characters)",
|
"account.new.password": "New password (min. 8, at least 3 character types)",
|
||||||
"account.password.heading": "Change password",
|
"account.password.heading": "Change password",
|
||||||
"account.password.saved": "Password updated",
|
"account.password.saved": "Password updated",
|
||||||
"account.profile.heading": "Profile",
|
"account.profile.heading": "Profile",
|
||||||
@@ -381,7 +380,7 @@ enum L10n {
|
|||||||
"account.save.password": "Update password",
|
"account.save.password": "Update password",
|
||||||
"account.save.profile": "Save profile",
|
"account.save.profile": "Save profile",
|
||||||
"account.title": "Account",
|
"account.title": "Account",
|
||||||
"forgot.password.lead": "Enter your account email: we'll send you a link to reset your password.",
|
"forgot.password.lead": "Enter your account email: we will send you a link to reset your password.",
|
||||||
"forgot.password.submit": "Send reset link",
|
"forgot.password.submit": "Send reset link",
|
||||||
"forgot.password.success": "If the email is registered, you will receive a password reset link shortly.",
|
"forgot.password.success": "If the email is registered, you will receive a password reset link shortly.",
|
||||||
"forgot.password.title": "Forgot password",
|
"forgot.password.title": "Forgot password",
|
||||||
@@ -485,7 +484,7 @@ enum L10n {
|
|||||||
"match.status.start": "START",
|
"match.status.start": "START",
|
||||||
"matches.active.team": "Active team: %1$@.",
|
"matches.active.team": "Active team: %1$@.",
|
||||||
"matches.change": "Change",
|
"matches.change": "Change",
|
||||||
"matches.empty.hint": "Schedule a match or start a new one with «New match».",
|
"matches.empty.hint": "Tap «New match» to schedule ahead or start right away.",
|
||||||
"matches.empty.title": "No matches on the calendar",
|
"matches.empty.title": "No matches on the calendar",
|
||||||
"matches.hello": "Hi, %1$@",
|
"matches.hello": "Hi, %1$@",
|
||||||
"matches.load.error": "Loading error",
|
"matches.load.error": "Loading error",
|
||||||
@@ -503,9 +502,8 @@ enum L10n {
|
|||||||
"matches.no.team.title": "No team assigned",
|
"matches.no.team.title": "No team assigned",
|
||||||
"matches.ready.title": "Ready to start",
|
"matches.ready.title": "Ready to start",
|
||||||
"matches.retry": "Retry",
|
"matches.retry": "Retry",
|
||||||
"matches.schedule": "Scheduled match",
|
|
||||||
"matches.scheduled.title": "Scheduled matches",
|
"matches.scheduled.title": "Scheduled matches",
|
||||||
"matches.subtitle": "Resume a live stream or start a scheduled match.",
|
"matches.subtitle": "Resume a live stream or start a new match.",
|
||||||
"matches.tap.change.team": "Tap to change team",
|
"matches.tap.change.team": "Tap to change team",
|
||||||
"matches.team.for.live": "Team for the live stream",
|
"matches.team.for.live": "Team for the live stream",
|
||||||
"matches.title": "Matches",
|
"matches.title": "Matches",
|
||||||
@@ -663,7 +661,7 @@ enum L10n {
|
|||||||
"account.confirm.password": "Confirmer le mot de passe",
|
"account.confirm.password": "Confirmer le mot de passe",
|
||||||
"account.current.password": "Mot de passe actuel",
|
"account.current.password": "Mot de passe actuel",
|
||||||
"account.name.label": "Nom",
|
"account.name.label": "Nom",
|
||||||
"account.new.password": "Nouveau mot de passe (min. 8 caractères)",
|
"account.new.password": "Nouveau mot de passe (min. 8, au moins 3 types de caractères)",
|
||||||
"account.password.heading": "Changer le mot de passe",
|
"account.password.heading": "Changer le mot de passe",
|
||||||
"account.password.saved": "Mot de passe mis à jour",
|
"account.password.saved": "Mot de passe mis à jour",
|
||||||
"account.profile.heading": "Profil",
|
"account.profile.heading": "Profil",
|
||||||
@@ -776,7 +774,7 @@ enum L10n {
|
|||||||
"match.status.start": "DÉMARRER",
|
"match.status.start": "DÉMARRER",
|
||||||
"matches.active.team": "Équipe active : %1$@.",
|
"matches.active.team": "Équipe active : %1$@.",
|
||||||
"matches.change": "Changer",
|
"matches.change": "Changer",
|
||||||
"matches.empty.hint": "Programmez un match ou démarrez-en un avec « Nouveau match ».",
|
"matches.empty.hint": "Touchez « Nouveau match » pour planifier à l'avance ou démarrer tout de suite.",
|
||||||
"matches.empty.title": "Aucun match au calendrier",
|
"matches.empty.title": "Aucun match au calendrier",
|
||||||
"matches.hello": "Bonjour, %1$@",
|
"matches.hello": "Bonjour, %1$@",
|
||||||
"matches.load.error": "Erreur de chargement",
|
"matches.load.error": "Erreur de chargement",
|
||||||
@@ -794,9 +792,8 @@ enum L10n {
|
|||||||
"matches.no.team.title": "Aucune équipe assignée",
|
"matches.no.team.title": "Aucune équipe assignée",
|
||||||
"matches.ready.title": "Prêts à démarrer",
|
"matches.ready.title": "Prêts à démarrer",
|
||||||
"matches.retry": "Réessayer",
|
"matches.retry": "Réessayer",
|
||||||
"matches.schedule": "Match programmé",
|
|
||||||
"matches.scheduled.title": "Matchs programmés",
|
"matches.scheduled.title": "Matchs programmés",
|
||||||
"matches.subtitle": "Reprenez un direct en cours ou démarrez un match programmé.",
|
"matches.subtitle": "Reprenez un direct en cours ou démarrez un nouveau match.",
|
||||||
"matches.tap.change.team": "Appuyez pour changer d'équipe",
|
"matches.tap.change.team": "Appuyez pour changer d'équipe",
|
||||||
"matches.team.for.live": "Équipe pour le direct",
|
"matches.team.for.live": "Équipe pour le direct",
|
||||||
"matches.title": "Matchs",
|
"matches.title": "Matchs",
|
||||||
@@ -954,7 +951,7 @@ enum L10n {
|
|||||||
"account.confirm.password": "Passwort bestätigen",
|
"account.confirm.password": "Passwort bestätigen",
|
||||||
"account.current.password": "Aktuelles Passwort",
|
"account.current.password": "Aktuelles Passwort",
|
||||||
"account.name.label": "Name",
|
"account.name.label": "Name",
|
||||||
"account.new.password": "Neues Passwort (mind. 8 Zeichen)",
|
"account.new.password": "Neues Passwort (mind. 8, mindestens 3 Zeichenarten)",
|
||||||
"account.password.heading": "Passwort ändern",
|
"account.password.heading": "Passwort ändern",
|
||||||
"account.password.saved": "Passwort aktualisiert",
|
"account.password.saved": "Passwort aktualisiert",
|
||||||
"account.profile.heading": "Profil",
|
"account.profile.heading": "Profil",
|
||||||
@@ -1067,7 +1064,7 @@ enum L10n {
|
|||||||
"match.status.start": "STARTEN",
|
"match.status.start": "STARTEN",
|
||||||
"matches.active.team": "Aktives Team: %1$@.",
|
"matches.active.team": "Aktives Team: %1$@.",
|
||||||
"matches.change": "Wechseln",
|
"matches.change": "Wechseln",
|
||||||
"matches.empty.hint": "Plane ein Spiel oder starte ein neues mit «Neues Spiel».",
|
"matches.empty.hint": "Tippe auf «Neues Spiel», um im Voraus zu planen oder sofort zu starten.",
|
||||||
"matches.empty.title": "Keine Spiele im Kalender",
|
"matches.empty.title": "Keine Spiele im Kalender",
|
||||||
"matches.hello": "Hallo, %1$@",
|
"matches.hello": "Hallo, %1$@",
|
||||||
"matches.load.error": "Ladefehler",
|
"matches.load.error": "Ladefehler",
|
||||||
@@ -1085,9 +1082,8 @@ enum L10n {
|
|||||||
"matches.no.team.title": "Kein Team zugewiesen",
|
"matches.no.team.title": "Kein Team zugewiesen",
|
||||||
"matches.ready.title": "Bereit zum Start",
|
"matches.ready.title": "Bereit zum Start",
|
||||||
"matches.retry": "Erneut versuchen",
|
"matches.retry": "Erneut versuchen",
|
||||||
"matches.schedule": "Geplantes Spiel",
|
|
||||||
"matches.scheduled.title": "Geplante Spiele",
|
"matches.scheduled.title": "Geplante Spiele",
|
||||||
"matches.subtitle": "Nimm einen laufenden Livestream wieder auf oder starte ein geplantes Spiel.",
|
"matches.subtitle": "Nimm einen laufenden Livestream wieder auf oder starte ein neues Spiel.",
|
||||||
"matches.tap.change.team": "Tippen zum Teamwechsel",
|
"matches.tap.change.team": "Tippen zum Teamwechsel",
|
||||||
"matches.team.for.live": "Team für den Livestream",
|
"matches.team.for.live": "Team für den Livestream",
|
||||||
"matches.title": "Spiele",
|
"matches.title": "Spiele",
|
||||||
@@ -1245,7 +1241,7 @@ enum L10n {
|
|||||||
"account.confirm.password": "Confirmar contraseña",
|
"account.confirm.password": "Confirmar contraseña",
|
||||||
"account.current.password": "Contraseña actual",
|
"account.current.password": "Contraseña actual",
|
||||||
"account.name.label": "Nombre",
|
"account.name.label": "Nombre",
|
||||||
"account.new.password": "Nueva contraseña (mín. 8 caracteres)",
|
"account.new.password": "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)",
|
||||||
"account.password.heading": "Cambiar contraseña",
|
"account.password.heading": "Cambiar contraseña",
|
||||||
"account.password.saved": "Contraseña actualizada",
|
"account.password.saved": "Contraseña actualizada",
|
||||||
"account.profile.heading": "Perfil",
|
"account.profile.heading": "Perfil",
|
||||||
@@ -1358,7 +1354,7 @@ enum L10n {
|
|||||||
"match.status.start": "INICIAR",
|
"match.status.start": "INICIAR",
|
||||||
"matches.active.team": "Equipo activo: %1$@.",
|
"matches.active.team": "Equipo activo: %1$@.",
|
||||||
"matches.change": "Cambiar",
|
"matches.change": "Cambiar",
|
||||||
"matches.empty.hint": "Programa un partido o inicia uno nuevo con «Nuevo partido».",
|
"matches.empty.hint": "Toca «Nuevo partido» para programar con antelación o empezar ya.",
|
||||||
"matches.empty.title": "Ningún partido en el calendario",
|
"matches.empty.title": "Ningún partido en el calendario",
|
||||||
"matches.hello": "Hola, %1$@",
|
"matches.hello": "Hola, %1$@",
|
||||||
"matches.load.error": "Error de carga",
|
"matches.load.error": "Error de carga",
|
||||||
@@ -1376,9 +1372,8 @@ enum L10n {
|
|||||||
"matches.no.team.title": "Ningún equipo asignado",
|
"matches.no.team.title": "Ningún equipo asignado",
|
||||||
"matches.ready.title": "Listos para empezar",
|
"matches.ready.title": "Listos para empezar",
|
||||||
"matches.retry": "Reintentar",
|
"matches.retry": "Reintentar",
|
||||||
"matches.schedule": "Partido programado",
|
|
||||||
"matches.scheduled.title": "Partidos programados",
|
"matches.scheduled.title": "Partidos programados",
|
||||||
"matches.subtitle": "Reanuda un directo en curso o inicia un partido programado.",
|
"matches.subtitle": "Reanuda un directo en curso o inicia un nuevo partido.",
|
||||||
"matches.tap.change.team": "Toca para cambiar de equipo",
|
"matches.tap.change.team": "Toca para cambiar de equipo",
|
||||||
"matches.team.for.live": "Equipo para el directo",
|
"matches.team.for.live": "Equipo para el directo",
|
||||||
"matches.title": "Partidos",
|
"matches.title": "Partidos",
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ final class MatchLiveAPI: @unchecked Sendable {
|
|||||||
request.httpMethod = "PATCH"
|
request.httpMethod = "PATCH"
|
||||||
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
||||||
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
||||||
|
request.setValue(AppLanguage.resolvedCode, forHTTPHeaderField: "Accept-Language")
|
||||||
if let accessToken { request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") }
|
if let accessToken { request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") }
|
||||||
request.httpBody = MultipartBuilder.build(fields: fields, boundary: boundary)
|
request.httpBody = MultipartBuilder.build(fields: fields, boundary: boundary)
|
||||||
return try await execute(request)
|
return try await execute(request)
|
||||||
@@ -253,6 +254,7 @@ final class MatchLiveAPI: @unchecked Sendable {
|
|||||||
var request = URLRequest(url: baseURL.appendingPathComponent(path))
|
var request = URLRequest(url: baseURL.appendingPathComponent(path))
|
||||||
request.httpMethod = method
|
request.httpMethod = method
|
||||||
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
||||||
|
request.setValue(AppLanguage.resolvedCode, forHTTPHeaderField: "Accept-Language")
|
||||||
if body != nil {
|
if body != nil {
|
||||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
request.httpBody = try ApiInstant.encoder.encode(body)
|
request.httpBody = try ApiInstant.encoder.encode(body)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.0.5</string>
|
<string>2.0.10</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>26</string>
|
<string>31</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct MatchPrimaryButton: View {
|
|||||||
.font(MatchTypography.labelLarge)
|
.font(MatchTypography.labelLarge)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.7)
|
.minimumScaleFactor(0.7)
|
||||||
|
.padding(.horizontal, 14)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
@@ -21,5 +21,8 @@ struct MatchScreenScaffold<Content: View, TopBar: View>: View {
|
|||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||||
.background(MatchColors.background)
|
.background(MatchColors.background)
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
|
// Chrome custom: nasconde la navigation bar di sistema (evita chevron indietro spurî).
|
||||||
|
.toolbar(.hidden, for: .navigationBar)
|
||||||
|
.navigationBarBackButtonHidden(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ struct MatchSecondaryButton: View {
|
|||||||
.font(MatchTypography.labelLarge)
|
.font(MatchTypography.labelLarge)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.7)
|
.minimumScaleFactor(0.7)
|
||||||
|
.padding(.horizontal, 14)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.frame(height: 52)
|
.frame(height: 52)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,10 +77,7 @@ struct MatchesScreen: View {
|
|||||||
Text(L10n.t("matches.subtitle"))
|
Text(L10n.t("matches.subtitle"))
|
||||||
.font(MatchTypography.bodyMedium)
|
.font(MatchTypography.bodyMedium)
|
||||||
.foregroundStyle(MatchColors.textSecondary)
|
.foregroundStyle(MatchColors.textSecondary)
|
||||||
HStack(spacing: 12) {
|
|
||||||
MatchSecondaryButton(label: L10n.t("matches.schedule").uppercased(), action: { showSchedule = true })
|
|
||||||
MatchPrimaryButton(label: L10n.t("matches.new").uppercased(), action: { showNewMatch = true })
|
MatchPrimaryButton(label: L10n.t("matches.new").uppercased(), action: { showNewMatch = true })
|
||||||
}
|
|
||||||
if let activeTeam {
|
if let activeTeam {
|
||||||
TeamPickerBar(
|
TeamPickerBar(
|
||||||
team: activeTeam,
|
team: activeTeam,
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct AppNavHost: View {
|
struct AppNavHost: View {
|
||||||
|
private enum RootScreen {
|
||||||
|
case splash
|
||||||
|
case login
|
||||||
|
case matches
|
||||||
|
}
|
||||||
|
|
||||||
@StateObject private var container = AppContainer()
|
@StateObject private var container = AppContainer()
|
||||||
|
@State private var root: RootScreen = .splash
|
||||||
|
/// Solo destinazioni sopra la root (account, recupero password).
|
||||||
@State private var path: [Routes] = []
|
@State private var path: [Routes] = []
|
||||||
@State private var wizardRoute: WizardRoute?
|
@State private var wizardRoute: WizardRoute?
|
||||||
@State private var broadcastRoute: BroadcastRoute?
|
@State private var broadcastRoute: BroadcastRoute?
|
||||||
@@ -17,46 +25,24 @@ struct AppNavHost: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $path) {
|
NavigationStack(path: $path) {
|
||||||
SplashScreen(
|
rootContent
|
||||||
container: container,
|
|
||||||
onAuthenticated: { path = [.matches] },
|
|
||||||
onUnauthenticated: { path = [.login] }
|
|
||||||
)
|
|
||||||
.navigationDestination(for: Routes.self) { route in
|
.navigationDestination(for: Routes.self) { route in
|
||||||
switch route {
|
switch route {
|
||||||
case .splash:
|
|
||||||
EmptyView()
|
|
||||||
case .login:
|
|
||||||
LoginScreen(
|
|
||||||
container: container,
|
|
||||||
onLoggedIn: { path = [.matches] },
|
|
||||||
onForgotPassword: { path.append(.forgotPassword) }
|
|
||||||
)
|
|
||||||
case .forgotPassword:
|
case .forgotPassword:
|
||||||
ForgotPasswordScreen(
|
ForgotPasswordScreen(
|
||||||
container: container,
|
container: container,
|
||||||
onBack: { path.removeLast() }
|
onBack: { path.removeLast() }
|
||||||
)
|
)
|
||||||
case .matches:
|
|
||||||
MatchesScreen(
|
|
||||||
container: container,
|
|
||||||
refreshToken: matchesRefreshToken,
|
|
||||||
onOpenSetup: { matchId in
|
|
||||||
wizardRoute = WizardRoute(matchId: matchId, step: 1)
|
|
||||||
},
|
|
||||||
onOpenBroadcast: { sessionId in
|
|
||||||
broadcastRoute = BroadcastRoute(sessionId: sessionId)
|
|
||||||
},
|
|
||||||
onOpenAccount: { path.append(.account) }
|
|
||||||
)
|
|
||||||
.lockPortraitOrientation()
|
|
||||||
case .account:
|
case .account:
|
||||||
AccountScreen(
|
AccountScreen(
|
||||||
container: container,
|
container: container,
|
||||||
onBack: { path.removeLast() },
|
onBack: { path.removeLast() },
|
||||||
onLoggedOut: { path = [.login] }
|
onLoggedOut: {
|
||||||
|
path = []
|
||||||
|
root = .login
|
||||||
|
}
|
||||||
)
|
)
|
||||||
case .setup, .broadcast:
|
case .splash, .login, .matches, .setup, .broadcast:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +84,8 @@ struct AppNavHost: View {
|
|||||||
AppOrientation.lockPortrait()
|
AppOrientation.lockPortrait()
|
||||||
container.wizardSession.reset()
|
container.wizardSession.reset()
|
||||||
broadcastRoute = nil
|
broadcastRoute = nil
|
||||||
path = [.matches]
|
path = []
|
||||||
|
root = .matches
|
||||||
}
|
}
|
||||||
.keepScreenOn()
|
.keepScreenOn()
|
||||||
}
|
}
|
||||||
@@ -109,4 +96,44 @@ struct AppNavHost: View {
|
|||||||
}
|
}
|
||||||
.environmentObject(container)
|
.environmentObject(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private var rootContent: some View {
|
||||||
|
switch root {
|
||||||
|
case .splash:
|
||||||
|
SplashScreen(
|
||||||
|
container: container,
|
||||||
|
onAuthenticated: {
|
||||||
|
path = []
|
||||||
|
root = .matches
|
||||||
|
},
|
||||||
|
onUnauthenticated: {
|
||||||
|
path = []
|
||||||
|
root = .login
|
||||||
|
}
|
||||||
|
)
|
||||||
|
case .login:
|
||||||
|
LoginScreen(
|
||||||
|
container: container,
|
||||||
|
onLoggedIn: {
|
||||||
|
path = []
|
||||||
|
root = .matches
|
||||||
|
},
|
||||||
|
onForgotPassword: { path.append(.forgotPassword) }
|
||||||
|
)
|
||||||
|
case .matches:
|
||||||
|
MatchesScreen(
|
||||||
|
container: container,
|
||||||
|
refreshToken: matchesRefreshToken,
|
||||||
|
onOpenSetup: { matchId in
|
||||||
|
wizardRoute = WizardRoute(matchId: matchId, step: 1)
|
||||||
|
},
|
||||||
|
onOpenBroadcast: { sessionId in
|
||||||
|
broadcastRoute = BroadcastRoute(sessionId: sessionId)
|
||||||
|
},
|
||||||
|
onOpenAccount: { path.append(.account) }
|
||||||
|
)
|
||||||
|
.lockPortraitOrientation()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ lines += [
|
|||||||
app_settings = """
|
app_settings = """
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = NO;
|
GENERATE_INFOPLIST_FILE = NO;
|
||||||
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
INFOPLIST_FILE = MatchLiveTv/Resources/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
@@ -107,7 +107,7 @@ app_settings = """
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
API_BASE_URL = "https://www.matchlivetv.it";
|
API_BASE_URL = "https://www.matchlivetv.it";
|
||||||
@@ -122,10 +122,10 @@ app_debug_settings = app_settings + """
|
|||||||
test_settings = """
|
test_settings = """
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 26;
|
CURRENT_PROJECT_VERSION = 31;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
MARKETING_VERSION = 2.0.5;
|
MARKETING_VERSION = 2.0.10;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.matchlivetv.match-live-tv.tests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
|||||||
Reference in New Issue
Block a user