diff options
| -rw-r--r-- | app/assets/stylesheets/wittle/general.css.scss | 33 | ||||
| -rw-r--r-- | app/controllers/wittle/puzzles_controller.rb | 4 | ||||
| -rw-r--r-- | app/helpers/wittle/puzzles_helper.rb | 5 | ||||
| -rw-r--r-- | app/views/wittle/puzzles/_handle_puzzle.html.erb | 32 | ||||
| -rw-r--r-- | app/views/wittle/puzzles/_submission.html.haml | 2 | ||||
| -rw-r--r-- | app/views/wittle/puzzles/show.html.haml | 14 |
6 files changed, 79 insertions, 11 deletions
| diff --git a/app/assets/stylesheets/wittle/general.css.scss b/app/assets/stylesheets/wittle/general.css.scss index b2b432d..9d893b6 100644 --- a/app/assets/stylesheets/wittle/general.css.scss +++ b/app/assets/stylesheets/wittle/general.css.scss | |||
| @@ -75,17 +75,46 @@ input[type="range"]::-ms-thumb { | |||
| 75 | 75 | ||
| 76 | #scores { | 76 | #scores { |
| 77 | display: flex; | 77 | display: flex; |
| 78 | 78 | ||
| 79 | div { | 79 | div { |
| 80 | flex: 0 0 48%; | 80 | flex: 0 0 48%; |
| 81 | 81 | ||
| 82 | h2 { | 82 | h2 { |
| 83 | text-align: center; | 83 | text-align: center; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | table { | 86 | table { |
| 87 | width: max-content; | 87 | width: max-content; |
| 88 | margin: 0 auto; | 88 | margin: 0 auto; |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | |||
| 93 | #activation-button { | ||
| 94 | button { | ||
| 95 | display: block; | ||
| 96 | margin: 0 auto; | ||
| 97 | width: 25%; | ||
| 98 | background-color: #04AA6D; | ||
| 99 | padding: 14px 28px; | ||
| 100 | font-size: 16px; | ||
| 101 | cursor: pointer; | ||
| 102 | text-align: center; | ||
| 103 | color: white; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | #timer { | ||
| 108 | width: max-content; | ||
| 109 | margin: 0.5em auto 0; | ||
| 110 | font-size: 3em; | ||
| 111 | |||
| 112 | %label { | ||
| 113 | padding: 0; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | .score-field { | ||
| 118 | padding-left: 1em; | ||
| 119 | text-align: right; | ||
| 120 | } | ||
| diff --git a/app/controllers/wittle/puzzles_controller.rb b/app/controllers/wittle/puzzles_controller.rb index 9599307..ed7087a 100644 --- a/app/controllers/wittle/puzzles_controller.rb +++ b/app/controllers/wittle/puzzles_controller.rb | |||
| @@ -24,6 +24,8 @@ module Wittle | |||
| 24 | @puzzle.save! | 24 | @puzzle.save! |
| 25 | end | 25 | end |
| 26 | 26 | ||
| 27 | @time = (params.include? :time) ? params[:time] : nil | ||
| 28 | |||
| 27 | session[:played_puzzles] ||= [] | 29 | session[:played_puzzles] ||= [] |
| 28 | session[:played_puzzles] << @puzzle.id | 30 | session[:played_puzzles] << @puzzle.id |
| 29 | end | 31 | end |
| @@ -33,7 +35,7 @@ module Wittle | |||
| 33 | 35 | ||
| 34 | raise ActiveRecord::RecordNotFound unless @puzzle.latest? | 36 | raise ActiveRecord::RecordNotFound unless @puzzle.latest? |
| 35 | 37 | ||
| 36 | @puzzle.scores.create!(name: params[:name], ip: request.ip) | 38 | @puzzle.scores.create!(name: params[:name], ip: request.ip, seconds_taken: (params.include? :time) ? params[:time] : nil) |
| 37 | 39 | ||
| 38 | redirect_to @puzzle | 40 | redirect_to @puzzle |
| 39 | end | 41 | end |
| diff --git a/app/helpers/wittle/puzzles_helper.rb b/app/helpers/wittle/puzzles_helper.rb index 6230940..64364c6 100644 --- a/app/helpers/wittle/puzzles_helper.rb +++ b/app/helpers/wittle/puzzles_helper.rb | |||
| @@ -1,4 +1,9 @@ | |||
| 1 | module Wittle | 1 | module Wittle |
| 2 | module PuzzlesHelper | 2 | module PuzzlesHelper |
| 3 | |||
| 4 | def humanize_interval(seconds) | ||
| 5 | "#{(seconds / 60).to_s.rjust(2, '0')}:#{(seconds % 60).to_s.rjust(2, '0')}" | ||
| 6 | end | ||
| 7 | |||
| 3 | end | 8 | end |
| 4 | end | 9 | end |
| diff --git a/app/views/wittle/puzzles/_handle_puzzle.html.erb b/app/views/wittle/puzzles/_handle_puzzle.html.erb index 3ac868e..3d593a4 100644 --- a/app/views/wittle/puzzles/_handle_puzzle.html.erb +++ b/app/views/wittle/puzzles/_handle_puzzle.html.erb | |||
| @@ -1,6 +1,23 @@ | |||
| 1 | <script type="text/javascript"> | 1 | <script type="text/javascript"> |
| 2 | var totalSeconds = 0 | ||
| 3 | var timerInterval | ||
| 4 | |||
| 2 | window.onload = function() { | 5 | window.onload = function() { |
| 3 | <% if @playable %> | 6 | <% if @playable %> |
| 7 | function pad(val) { | ||
| 8 | var valString = val + "" | ||
| 9 | if (valString.length < 2) | ||
| 10 | { | ||
| 11 | return "0" + valString | ||
| 12 | } else { | ||
| 13 | return valString | ||
| 14 | } | ||
| 15 | } | ||
| 16 | function setTime() { | ||
| 17 | ++totalSeconds | ||
| 18 | $("#seconds").text(pad(totalSeconds%60)) | ||
| 19 | $("#minutes").text(pad(parseInt(totalSeconds/60))) | ||
| 20 | } | ||
| 4 | $("#sens").val(window.settings.sensitivity) | 21 | $("#sens").val(window.settings.sensitivity) |
| 5 | $("#sens").on("change", function() { | 22 | $("#sens").on("change", function() { |
| 6 | window.settings.sensitivity = this.value | 23 | window.settings.sensitivity = this.value |
| @@ -9,12 +26,17 @@ window.onload = function() { | |||
| 9 | $("#volume").on("change", function() { | 26 | $("#volume").on("change", function() { |
| 10 | window.settings.volume = this.value | 27 | window.settings.volume = this.value |
| 11 | }) | 28 | }) |
| 12 | <% end %> | 29 | $("#activation-button button").on("click", function() { |
| 30 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") | ||
| 31 | draw(puzzle) | ||
| 32 | |||
| 33 | $("#activation-button").hide() | ||
| 13 | 34 | ||
| 35 | timerInterval = setInterval(setTime, 1000); | ||
| 36 | }) | ||
| 37 | <% else %> | ||
| 14 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") | 38 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") |
| 15 | draw(puzzle) | 39 | draw(puzzle) |
| 16 | |||
| 17 | <% unless @playable %> | ||
| 18 | drawPath(puzzle, JSON.parse("<%= escape_javascript(sanitize @puzzle.solved_data) %>")) | 40 | drawPath(puzzle, JSON.parse("<%= escape_javascript(sanitize @puzzle.solved_data) %>")) |
| 19 | window.trace = function() {} | 41 | window.trace = function() {} |
| 20 | <% end %> | 42 | <% end %> |
| @@ -22,10 +44,12 @@ window.onload = function() { | |||
| 22 | 44 | ||
| 23 | <% if @playable %> | 45 | <% if @playable %> |
| 24 | window.TRACE_COMPLETION_FUNC = function(puzzle, rawPath) { | 46 | window.TRACE_COMPLETION_FUNC = function(puzzle, rawPath) { |
| 47 | clearInterval(timerInterval) | ||
| 48 | |||
| 25 | $.ajax({ | 49 | $.ajax({ |
| 26 | type: "POST", | 50 | type: "POST", |
| 27 | url: "<%= solve_puzzle_path(@puzzle, format: :js) %>", | 51 | url: "<%= solve_puzzle_path(@puzzle, format: :js) %>", |
| 28 | data: { solved: JSON.stringify(rawPath) } | 52 | data: { solved: JSON.stringify(rawPath), time: totalSeconds } |
| 29 | }) | 53 | }) |
| 30 | } | 54 | } |
| 31 | 55 | ||
| diff --git a/app/views/wittle/puzzles/_submission.html.haml b/app/views/wittle/puzzles/_submission.html.haml index 744372a..a3d0740 100644 --- a/app/views/wittle/puzzles/_submission.html.haml +++ b/app/views/wittle/puzzles/_submission.html.haml | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | %h3 Congrats! | 1 | %h3 Congrats! |
| 2 | %p Would you like to submit your time? | 2 | %p Would you like to submit your time? |
| 3 | = form_with url: submit_puzzle_path(@puzzle) do |form| | 3 | = form_with url: submit_puzzle_path(@puzzle) do |form| |
| 4 | - unless @time.nil? | ||
| 5 | = form.hidden_field :time, value: @time | ||
| 4 | %p | 6 | %p |
| 5 | = form.label :name, "Name:" | 7 | = form.label :name, "Name:" |
| 6 | = form.text_field :name | 8 | = form.text_field :name |
| diff --git a/app/views/wittle/puzzles/show.html.haml b/app/views/wittle/puzzles/show.html.haml index 75ae288..deda344 100644 --- a/app/views/wittle/puzzles/show.html.haml +++ b/app/views/wittle/puzzles/show.html.haml | |||
| @@ -3,6 +3,12 @@ | |||
| 3 | %svg#puzzle{ style: "pointer-events: auto"} | 3 | %svg#puzzle{ style: "pointer-events: auto"} |
| 4 | #submission-form | 4 | #submission-form |
| 5 | - if @playable | 5 | - if @playable |
| 6 | #activation-button | ||
| 7 | %button{ type: "button" } Reveal Puzzle | ||
| 8 | #timer | ||
| 9 | %label#minutes 00 | ||
| 10 | %label#colon : | ||
| 11 | %label#seconds 00 | ||
| 6 | %details#trace-settings | 12 | %details#trace-settings |
| 7 | %summary Settings | 13 | %summary Settings |
| 8 | .things | 14 | .things |
| @@ -15,17 +21,17 @@ | |||
| 15 | #by-time | 21 | #by-time |
| 16 | %h2 Fastest Solves | 22 | %h2 Fastest Solves |
| 17 | %table | 23 | %table |
| 18 | - @puzzle.scores.where("seconds_taken IS NOT NULL").order(seconds_taken: :asc).each do |score| | 24 | - @puzzle.scores.where("seconds_taken IS NOT NULL").order(seconds_taken: :asc).limit(20).each_with_index do |score, i| |
| 19 | %tr | 25 | %tr |
| 20 | %td #{(i + 1)}. | 26 | %td #{(i + 1)}. |
| 21 | %td= score.name | 27 | %td= score.name |
| 22 | %td | 28 | %td.score-field= humanize_interval(score.seconds_taken) |
| 23 | #by-when | 29 | #by-when |
| 24 | %h2 Completion Order | 30 | %h2 Completion Order |
| 25 | %table | 31 | %table |
| 26 | - @puzzle.scores.order(created_at: :asc).each_with_index do |score, i| | 32 | - @puzzle.scores.order(created_at: :asc).limit(20).each_with_index do |score, i| |
| 27 | %tr | 33 | %tr |
| 28 | %td #{(i + 1)}. | 34 | %td #{(i + 1)}. |
| 29 | %td= score.name | 35 | %td= score.name |
| 30 | %td= score.created_at.getlocal().strftime("%-I:%M:%S%P") | 36 | %td.score-field= score.created_at.getlocal().strftime("%-I:%M:%S%P") |
| 31 | = render partial: "handle_puzzle" | 37 | = render partial: "handle_puzzle" |
