diff --git a/app/models/concerns/heartbeatable.rb b/app/models/concerns/heartbeatable.rb index 1976b63..5a5889a 100644 --- a/app/models/concerns/heartbeatable.rb +++ b/app/models/concerns/heartbeatable.rb @@ -19,6 +19,36 @@ module Heartbeatable end end + def streak_days(start_date: 8.days.ago) + scope = coding_only.with_valid_timestamps + days = scope.daily_durations(start_date: start_date, end_date: Time.current) + .sort_by { |date, _| date } + .reverse + + streak = 0 + days.each do |date, duration| + if duration >= 15 * 60 + streak += 1 + else + break + end + end + + streak + end + + def streak_days_formatted(start_date: 8.days.ago) + result = streak_days(start_date: start_date) + + if result > 7 + "7+" + elsif result < 1 + nil + else + result.to_s + end + end + def duration_formatted(scope = all) seconds = duration_seconds(scope) hours = seconds / 3600 diff --git a/app/models/user.rb b/app/models/user.rb index 8f94225..c402780 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -23,6 +23,8 @@ class User < ApplicationRecord has_many :api_keys + delegate :streak_days, :streak_days_formatted, to: :heartbeats + enum :hackatime_extension_text_type, { simple_text: 0, clock_emoji: 1, diff --git a/app/views/leaderboards/_mini_leaderboard.html.erb b/app/views/leaderboards/_mini_leaderboard.html.erb index 298e4dd..e98cbe8 100644 --- a/app/views/leaderboards/_mini_leaderboard.html.erb +++ b/app/views/leaderboards/_mini_leaderboard.html.erb @@ -51,6 +51,15 @@ working on <%= link_to @active_projects[entry.user_id].project_name, @active_projects[entry.user_id].repo_url, target: "_blank" %> <% end %> + <% if entry.streak_count > 7 %> + + 🔥 7+ + + <% elsif entry.streak_count > 0 %> + + 🔥 <%= entry.streak_count %> + + <% end %> <%= short_time_detailed entry.total_seconds %> diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb index 54eda46..64cb9f4 100644 --- a/app/views/shared/_nav.html.erb +++ b/app/views/shared/_nav.html.erb @@ -10,6 +10,11 @@ <% if current_user %>
  • <%= render "shared/user_mention", user: current_user %> + <% if current_user.streak_days_formatted %> +

    + <%= current_user.streak_days_formatted %> 🔥 +

    + <% end %> <% if current_user.active_project && current_user.active_project_duration > 60 %>

    Working on: <%= current_user.active_project %> diff --git a/db/migrate/20250324203539_add_streak_count_to_leaderboard_entries.rb b/db/migrate/20250324203539_add_streak_count_to_leaderboard_entries.rb new file mode 100644 index 0000000..548a95a --- /dev/null +++ b/db/migrate/20250324203539_add_streak_count_to_leaderboard_entries.rb @@ -0,0 +1,5 @@ +class AddStreakCountToLeaderboardEntries < ActiveRecord::Migration[8.0] + def change + add_column :leaderboard_entries, :streak_count, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index db64e5c..fe652ab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_03_19_193636) do +ActiveRecord::Schema[8.0].define(version: 2025_03_24_203539) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -162,6 +162,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_19_193636) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.bigint "user_id", null: false + t.integer "streak_count", default: 0 t.index ["leaderboard_id", "user_id"], name: "idx_leaderboard_entries_on_leaderboard_and_user", unique: true t.index ["leaderboard_id"], name: "index_leaderboard_entries_on_leaderboard_id" end