Add tracking for scrapyard pins

This commit is contained in:
Max Wofford
2025-03-15 21:14:12 -04:00
parent a3d9ea9f5b
commit 7a141fb94b
2 changed files with 44 additions and 18 deletions

View File

@@ -1,10 +1,16 @@
class ScrapyardLeaderboardsController < ApplicationController
# March 14, 2024 at 8:00 PM Eastern
TRACKING_START_TIME = Time.find_zone("Eastern Time (US & Canada)").local(2025, 3, 14, 20, 0).to_i
PINNED_EVENT_TIMEOUT = 1.minutes
def index
@sort_by = params[:sort] == "average" ? "average" : "total"
# If there's a pinned event, cache it
if params[:event_pin].present?
mark_event_as_pinned(params[:event_pin])
end
# Cache the expensive computations for 10 seconds
@event_stats = Rails.cache.fetch("scrapyard_leaderboard_stats", expires_in: 10.seconds) do
# Get all attendees and their emails in one query
@@ -63,6 +69,15 @@ class ScrapyardLeaderboardsController < ApplicationController
-stats[:total_seconds]
end
end
# Get currently pinned events
@pinned_events = get_pinned_events
end
def pin
event_id = params[:id]
mark_event_as_pinned(event_id)
head :ok
end
def show
@@ -104,4 +119,25 @@ class ScrapyardLeaderboardsController < ApplicationController
stats.sort_by { |stats| -stats[:total_seconds] }
end
end
private
def mark_event_as_pinned(event_id)
Rails.cache.write(
"pinned_event:#{event_id}",
true,
expires_in: PINNED_EVENT_TIMEOUT
)
end
def get_pinned_events
# Get all cache keys for pinned events
cache_keys = Rails.cache.instance_variable_get(:@data)
.keys
.select { |k| k.start_with?("pinned_event:") }
return [] if cache_keys.empty?
event_ids = cache_keys.map { |k| k.split(":").last }
Warehouse::ScrapyardEvent.where(id: event_ids)
end
end

View File

@@ -14,7 +14,7 @@
<% @event_stats.each_with_index do |stats, index| %>
<div class="event-card" id="event-<%= stats[:event].id %>">
<a href="#<%= stats[:event].id %>" class="pin-link" title="Copy link to this event">📌</a>
<a href="?event_pin=<%= stats[:event].id %>" class="pin-link" title="Pin this event">📌</a>
<h2>
<%= link_to scrapyard_leaderboard_path(stats[:event]) do %>
<% case index %>
@@ -28,6 +28,9 @@
<span class="ordinal"><%= (index + 1).ordinalize %></span>
<% end %>
<%= stats[:event].name %>
<% if @pinned_events.include?(stats[:event]) %>
<span title="Currently being watched">👀</span>
<% end %>
<% end %>
</h2>
<div class="stats">
@@ -62,8 +65,8 @@
<% content_for :head do %>
<script>
function handlePin() {
console.log("Handling pin");
const pinId = window.location.hash.substring(1);
const params = new URLSearchParams(window.location.search);
const pinId = params.get('event_pin');
if (pinId) {
const targetCard = document.getElementById('event-' + pinId);
@@ -84,28 +87,15 @@
}
}
// Add click handlers to pin links
document.addEventListener('turbo:load', function() {
document.querySelectorAll('.pin-link').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const hash = this.getAttribute('href');
window.location.hash = hash;
handlePin();
window.location.reload();
});
});
});
// Handle both initial page load and subsequent Turbo navigations
document.addEventListener('turbo:load', handlePin);
document.addEventListener('turbo:render', handlePin);
document.addEventListener('DOMContentLoaded', handlePin);
window.addEventListener('hashchange', handlePin);
// Set up auto-refresh if we have a pin
document.addEventListener('turbo:load', function() {
if (window.location.hash) {
const params = new URLSearchParams(window.location.search);
if (params.has('event_pin')) {
// Clear any existing refresh interval
if (window.refreshInterval) {
clearInterval(window.refreshInterval);