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
30 changes: 30 additions & 0 deletions app/assets/stylesheets/components/_feed.scss
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,19 @@
background: var(--color-brand-salmon);
}

// Reassurance banner shown when a just-finished timelapse is being carried
// into this devlog (Lookout recording → "Add it to a devlog").
&__timelapse-note {
margin: 0 0 var(--space-xs);
padding: var(--space-xs);
border: 1px solid var(--color-brand-mint);
border-radius: var(--border-radius);
background: var(--color-space-accent-soft);
color: var(--color-space-text);
font-size: calc(var(--font-size-s) * 1.1);
line-height: 1.4;
}

&__form {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -841,6 +854,23 @@
font-size: calc(var(--font-size-s) * 1.2);
}

&__timelapse {
display: inline-flex;
align-items: center;
gap: var(--space-xxs);
margin: var(--space-xxs) 0 0;
font-size: calc(var(--font-size-s) * 1.1);
color: var(--color-brand-mint);
}

&__timelapse-dot {
flex: 0 0 auto;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--color-brand-mint);
}

&__body {
padding-left: var(--feed-content-offset);
font-size: calc(var(--font-size-s) * 1.2);
Expand Down
6 changes: 6 additions & 0 deletions app/components/posts/card_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
<p class="feed-post-card__duration"><%= helpers.format_seconds(display_postable.duration_seconds) %> logged</p>
<% end %>

<% if devlog? && current_user && Flipper.enabled?(:timelapse_devlog, current_user) && display_postable.lookout_sessions.exists? %>
<p class="feed-post-card__timelapse">
<span class="feed-post-card__timelapse-dot" aria-hidden="true"></span>Timelapse attached
</p>
<% end %>

<% if quote_repost? && body.present? %>
<div class="feed-post-card__body feed-post-card__body--inline markdown-content">
<%= helpers.md(body, allow_images: false) %>
Expand Down
8 changes: 8 additions & 0 deletions app/components/posts/composer_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
action: class_names("submit->composer#guardSubmit", "paste->composer#paste": show_attachments?) } },
class: "feed-composer__form",
local: true do |f| %>
<% if pending_lookout_session.present? %>
<%# Carried over from a just-finished Lookout recording: link that
session to this devlog, and reassure the user we kept their lapse. %>
<%= hidden_field_tag "post_devlog[lookout_session_ids][]", pending_lookout_session.id %>
<div class="feed-composer__timelapse-note" role="status">
Your timelapse<% if pending_lookout_session.duration_seconds.to_i > 0 %> (<%= helpers.format_seconds(pending_lookout_session.duration_seconds) %>)<% end %> is saved and will be attached to this devlog.
</div>
<% end %>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Project chip drops timelapse link

Medium Severity

After recording, the composer keeps a hidden post_devlog[lookout_session_ids][] for the timelapse and tells the user it will attach, but the project-page composer still shows project chips. Choosing another chip retargets the form to that project’s devlogs endpoint while the hidden id still refers to a session scoped to the original project, so attach_lookout_sessions finds no row and the timelapse is not linked.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eb3dd94. Configure here.

<div class="feed-composer__scroll">
<div class="feed-composer__main" data-markdown-preview-target="writePanel">
<%= image_tag current_user.avatar, alt: "", class: "feed-composer__avatar" %>
Expand Down
5 changes: 3 additions & 2 deletions app/components/posts/composer_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ class ComposerComponent < ViewComponent::Base
attr_reader :post, :current_user, :projects, :selected_project, :test_time_granted,
:url, :scope, :aria_label, :body_label, :placeholder, :submit_text,
:disable_with, :simple_mode, :show_project_chips, :show_attachments,
:show_time_preview, :show_record, :quote_preview_post
:show_time_preview, :show_record, :quote_preview_post, :pending_lookout_session

def initialize(post:, current_user:, projects:, selected_project:, test_time_granted: false,
url: nil, scope: nil, aria_label: "Create a devlog", body_label: "What are you working on?",
placeholder: "What are you working on?", submit_text: "Post", disable_with: "Posting...",
simple_mode: false, show_project_chips: true, show_attachments: true, show_time_preview: true,
show_record: false, quote_preview_post: nil)
show_record: false, quote_preview_post: nil, pending_lookout_session: nil)
@post = post
@current_user = current_user
@projects = projects
Expand All @@ -32,6 +32,7 @@ def initialize(post:, current_user:, projects:, selected_project:, test_time_gra
@show_time_preview = show_time_preview
@show_record = show_record
@quote_preview_post = quote_preview_post
@pending_lookout_session = pending_lookout_session
end

# When a post to quote is supplied, the composer shows it below the text box
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def prepare_project_show_context
@composer_devlog = Post::Devlog.new
@composer_projects = current_user.projects.order(updated_at: :desc)

# Coming back from a just-finished Lookout recording: pre-link that
# session to the devlog the user is about to write, so their timelapse
# attaches to the post instead of feeling lost.
if Flipper.enabled?(:timelapse_devlog, current_user) && params[:lookout_session_id].present?
@pending_lookout_session = @project.lookout_sessions.linkable
.find_by(id: params[:lookout_session_id], user: current_user, devlog_id: nil)
Comment thread
cursor[bot] marked this conversation as resolved.
end

@hackatime_linked = current_user.hackatime_identity.present?

if @hackatime_linked
Expand Down
24 changes: 24 additions & 0 deletions app/javascript/controllers/modal_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class extends Controller {

this.openSettingsModalFromQueryParam();
this.openIdvModalFromQueryParam();
this.openComposerModalFromQueryParam();
}

disconnect() {
Expand Down Expand Up @@ -130,4 +131,27 @@ export default class extends Controller {
}`;
window.history.replaceState(window.history.state, "", nextUrl);
}

// Landing on the project page straight from a finished Lookout recording
// (?just_recorded=1): pop the devlog composer open so the timelapse can be
// attached, then strip just_recorded so a refresh doesn't reopen it.
// Keep lookout_session_id: it's what the server reads to render the hidden
// attach field, so dropping it would lose the link on a pre-submit refresh.
openComposerModalFromQueryParam() {
if (!this.element.id.startsWith("composer-modal-")) return;

const params = new URLSearchParams(window.location.search);
if (!params.has("just_recorded")) return;

if (!this.element.open) {
this.element.showModal();
}

params.delete("just_recorded");
const query = params.toString();
const nextUrl = `${window.location.pathname}${query ? `?${query}` : ""}${
window.location.hash
}`;
window.history.replaceState(window.history.state, "", nextUrl);
Comment thread
cursor[bot] marked this conversation as resolved.
}
}
7 changes: 7 additions & 0 deletions app/models/lookout_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class LookoutSession < ApplicationRecord

scope :for_project, ->(project) { where(project: project) }
scope :attachable, -> { where(status: %w[stopped complete]) }
# Sessions that can be linked to a devlog from the recorder → composer flow.
# Broader than `attachable` (which requires a finished video): a session still
# `compiling` will finalize shortly, and the submit-side attach accepts any
# status, so the composer must surface the attach field for it too. Otherwise
# a background sync flipping stopped → compiling mid-flow silently drops the
# link. Excludes `failed` and the still-recording states.
scope :linkable, -> { where(status: %w[stopped compiling complete]) }
# Sessions that might still advance — everything not yet in a terminal state.
# SyncPendingLookoutSessionsJob re-polls these so a recording can finalize even
# when the builder closed the recorder tab before Lookout finished compiling.
Expand Down
11 changes: 9 additions & 2 deletions app/views/projects/lookout_sessions/record.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,15 @@

<%# Shown after the time is sent — nudge to actually log it in a devlog. %>
<div class="lookout-rec__post-prompt" data-lookout-capture-target="postPrompt" hidden>
<%= link_to "Post a Devlog", project_path(@project), class: "lookout-rec__post-btn" %>
<p class="lookout-rec__post-sub">Your time only counts once you do a devlog.</p>
<% if Flipper.enabled?(:timelapse_devlog, current_user) %>
<%= link_to "Add it to a devlog",
project_path(@project, lookout_session_id: @lookout_session.id, just_recorded: 1),
class: "lookout-rec__post-btn" %>
<p class="lookout-rec__post-sub">Saved! We've got your timelapse. Add it to a devlog so your time counts.</p>
<% else %>
<%= link_to "Post a Devlog", project_path(@project), class: "lookout-rec__post-btn" %>
<p class="lookout-rec__post-sub">Your time only counts once you do a devlog.</p>
<% end %>
</div>

<%= link_to "Back to project →", project_path(@project),
Expand Down
3 changes: 2 additions & 1 deletion app/views/projects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,8 @@
current_user: current_user,
projects: @composer_projects,
selected_project: @project,
test_time_granted: @test_time_granted
test_time_granted: @test_time_granted,
pending_lookout_session: @pending_lookout_session
) %>
</dialog>
<% end %>
Expand Down
1 change: 1 addition & 0 deletions config/initializers/flipper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
ship_event_payouts
lookout
payout_recommendations
timelapse_devlog
].each { |flag| Flipper.add(flag) }
end
rescue StandardError => e
Expand Down