From a1736ff076a2b3e3b273c5ea568d34052a0871a1 Mon Sep 17 00:00:00 2001 From: sto Date: Fri, 7 Nov 2025 09:30:04 +0100 Subject: [PATCH] Restrict offline participation to single-puzzle contests --- app/policies/contest_policy.rb | 2 +- app/views/contests/_form.html.slim | 15 ++++++++++++--- app/views/contests/_selectors.html.slim | 2 +- app/views/contests/scoreboard.html.slim | 2 +- app/views/contests/show.html.slim | 2 +- config/locales/en.yml | 3 ++- config/locales/fr.yml | 3 ++- 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/policies/contest_policy.rb b/app/policies/contest_policy.rb index 62a0f4a..d973f49 100644 --- a/app/policies/contest_policy.rb +++ b/app/policies/contest_policy.rb @@ -48,7 +48,7 @@ class ContestPolicy < ApplicationPolicy end def offline? - record.offline_form + record.offline_form && record.puzzles.length < 2 end def offline_new? diff --git a/app/views/contests/_form.html.slim b/app/views/contests/_form.html.slim index 8881b12..b10a5b3 100644 --- a/app/views/contests/_form.html.slim +++ b/app/views/contests/_form.html.slim @@ -17,9 +17,18 @@ h4.mt-5 = t("contests.form.general") = form.label :public .row.mb-3 .col - .form-check.form-switch - = form.check_box :offline_form, class: "form-check-input" - = form.label :offline_form + - if @contest.puzzles.length <= 1 + .form-check.form-switch + = form.check_box :offline_form, class: "form-check-input" + = form.label :offline_form + .form-text = t("activerecord.attributes.contest.offline_form_warning") + .form-text = t("activerecord.attributes.contest.offline_form_description") + - else + .form-check.form-switch + = form.check_box :offline_form_fake, class: "form-check-input", disabled: true + = form.label :offline_form + .form-text = t("activerecord.attributes.contest.offline_form_warning") + .form-text = t("activerecord.attributes.contest.offline_form_description") .row.mb-3 .col .form-check.form-switch diff --git a/app/views/contests/_selectors.html.slim b/app/views/contests/_selectors.html.slim index a2e94ff..031767f 100644 --- a/app/views/contests/_selectors.html.slim +++ b/app/views/contests/_selectors.html.slim @@ -29,7 +29,7 @@ javascript: categorySelectEl.addEventListener('change', (e) => { updateParams(); }) -- if @contest.offline_form +- if @contest.offline_form && @contest.puzzles.length < 2 .row .col input type="checkbox" id="offline" style="padding: 5px;" diff --git a/app/views/contests/scoreboard.html.slim b/app/views/contests/scoreboard.html.slim index 1f32aa2..1652c40 100644 --- a/app/views/contests/scoreboard.html.slim +++ b/app/views/contests/scoreboard.html.slim @@ -68,7 +68,7 @@ css: - @contest.puzzles.each do |puzzle| = image_tag(puzzle.image, class: "img-fluid ms-3 me-3", style: "max-height: 220px") if puzzle.image.attached? - = render "category_selector" + = render "selectors" .d-flex.flex-column style="overflow-y: auto" table.table.table-striped.table-hover diff --git a/app/views/contests/show.html.slim b/app/views/contests/show.html.slim index 4299dc7..8639f99 100644 --- a/app/views/contests/show.html.slim +++ b/app/views/contests/show.html.slim @@ -20,7 +20,7 @@ javascript: - else a.btn.btn-success.disabled = t("contests.show.public_scoreboard_disabled") - - if @contest.offline_form + - if @contest.offline_form && @contest.puzzles.length < 2 a.ms-3.btn.btn-success href="/public/#{@contest.slug}/offline" = t("contests.show.open_offline_form") - else diff --git a/config/locales/en.yml b/config/locales/en.yml index a8dafe7..e22d100 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,7 +54,8 @@ en: lang: Language for the public scoreboard name: Name offline_form: Enable the offline participation form - offline_form_description: Offline participants will have to fill the form by providing an image taken of the undone puzzle, and validate their finish time with an upload of an image of the completed puzzle + offline_form_description: Offline participants will have to fill the form by providing an image taken of the puzzle before starting solving it, and validate their finish time with an upload of an image of the completed puzzle + offline_form_warning: Only for single-puzzle contests public: Enable the public scoreboard team: Team contest team_description: For UI display purposes mainly diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 423f42c..12950e8 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -25,7 +25,8 @@ fr: lang: Langue pour le classement public name: Nom offline_form: Activer le formulaire de participation hors-ligne - offline_form_description: Les participant.e.s hors-ligne pourront participer en prenant une photo du puzzle non fait, puis valider leur temps avec une photo du puzzle une fois complété + offline_form_description: Les participant.e.s hors-ligne pourront participer en prenant une photo du puzzle avant de le commencer, puis valider leur temps avec une photo du puzzle une fois complété + offline_form_warning: Activable uniquement pour les concours avec un seul puzzle public: Activer le classement public team: Concours par équipes team_description: Principalement pour des raisons d'affichage