Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/controllers/daily_rolls_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def leaderboard
@viewer_rank = @viewer_date_roll.rank
@viewer_page = ((@viewer_rank - 1) / PAGE_SIZE) + 1
end
@lookout_banner_origin = lookout_banner_origin
else
@anonymous_roll = AnonymousRoll.new(cookies).today
end
Expand Down Expand Up @@ -101,6 +102,22 @@ def roll_for_anonymous
locals: { roll: roll, just_rolled: just_rolled, anonymous: true }) ]
end

# Re-engagement: the daily roll pulls even people who never track time back
# here, so signed-in viewers who haven't linked Hackatime get a banner nudging
# them toward Lookout. Returns where /auth/hackatime should send them afterward
# (their most recent project, so the on-project record flow is one click away),
# or nil when the banner shouldn't show. Kept cheap on purpose — keyed off the
# identity association, never a live Hackatime sync, which would add an API call
# to this hot path. Broadening to "linked but 0 hours" needs a cached hours
# signal first.
def lookout_banner_origin
return unless Flipper.enabled?(:lookout, current_user)
return if current_user.hackatime_identity.present?

recent_project = current_user.projects.order(created_at: :desc).first
recent_project ? project_path(recent_project) : rng_path

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong project recency ordering

Medium Severity

lookout_nudge_origin picks the Hackatime return destination with projects.order(created_at: :desc), but elsewhere the app treats the user’s active project as projects.order(updated_at: :desc) (home composer and project show). After linking, users with multiple projects can land on a stale or empty project instead of the one they actually use.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 09abf17. Configure here.

end

# rng ships with the week 2 release; until then it 404s for everyone.
def require_week_2_release
head :not_found unless Flipper.enabled?(:week_2_release, current_user)
Expand Down
1 change: 1 addition & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
<% end %>
<div id="flash-region"><%= render "shared/flash" %></div>
<%= render Onboarding::GuestBannerComponent.new unless @hide_sidebar %>
<%= render "shared/lookout_banner", origin: @lookout_banner_origin if @lookout_banner_origin %>
<% if @_admin_layout %>
<div class="admin-content"><%= yield %></div>
<% else %>
Expand Down
18 changes: 18 additions & 0 deletions app/views/shared/_lookout_banner.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<%# Top sticky re-engagement banner. Reuses the .guest-banner styling — the
yellow bar shown when you don't have a Hack Club account (see
components/_onboarding.scss) — so it sits at the top of the screen exactly
like that banner. Rendered from the application layout when the controller
set @lookout_banner_origin (currently only on /rng, for signed-in viewers
who are behind :lookout and haven't linked Hackatime yet).
Locals: origin (required — where /auth/hackatime returns them). %>
<div class="guest-banner" id="lookout-banner" role="status">
<p class="guest-banner__copy">
the easy way to log your build time — just hit record in your browser with Lookout. no install, no editor extension.
</p>
<%= button_to "Log hours with Lookout", "/auth/hackatime",
method: :post,
params: { origin: origin },
class: "guest-banner__cta",
form: { class: "guest-banner__form" },
data: { turbo: false } %>
</div>