Skip to content
Draft
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
2 changes: 1 addition & 1 deletion app/helpers/projects_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def leaderboard(you, sort: "week")
mine = project == you
{ rank:, you: mine, name: mine ? "You" : project.user.public_name,
user: project.user, building: project.title, off: !project.set_up?,
screenshot: (project.screenshot if project.screenshot.attached? && project.screenshot.blob.persisted?),
screenshot: project.stored_screenshot,
hours: project.hours_this_week, streak: project.streak,
flame: project.streak >= Reward.definition("flame")[:days], buddy: leaderboard_buddy(project) }
end
Expand Down
12 changes: 11 additions & 1 deletion app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,23 @@ def ship_in_review
ships.in_review.order(:created_at).last
end

# The screenshot, unless its file has gone from storage. The blob's row can outlive the file, and showing that one
# is a broken image.
def stored_screenshot
return unless screenshot.attached? && screenshot.blob.persisted?
return screenshot if screenshot.blob.service.exist?(screenshot.blob.key)

PosthogLog.warn("screenshot_file_missing")
nil
end

# Shipping: what you submit becomes your project's name and repo too, and the screenshot you pick (or the one you
# had) is kept with the ship.
def ship!(params)
upload = params.delete(:screenshot)
ship = ships.build(params.merge(hackatime_projects:, hours: hours_logged))
if upload.present? then ship.screenshot.attach(upload)
elsif screenshot.attached? then ship.screenshot.attach(screenshot.blob)
elsif (kept = stored_screenshot) then ship.screenshot.attach(kept.blob)
end

if ship.save
Expand Down
2 changes: 1 addition & 1 deletion app/views/buddies/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<span class="buddy-card__note"><%= buddy.title %> · Day <%= buddy.day_number %></span>
</span>
</div>
<% if (shot = buddy.screenshot).attached? && shot.blob.persisted? %>
<% if (shot = buddy.stored_screenshot) %>
<%= image_tag url_for(shot), alt: "Screenshot of #{buddy.title}", class: "buddy-card__shot" %>
<% end %>
</section>
Expand Down
2 changes: 1 addition & 1 deletion app/views/buddy_invites/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</div>

<div class="buddy-invited__project">
<% if (shot = @inviter.screenshot).attached? && shot.blob.persisted? %>
<% if (shot = @inviter.stored_screenshot) %>
<%= image_tag url_for(shot), alt: "Screenshot of #{@inviter.title}", class: "buddy-invited__shot" %>
<% end %>
<div class="buddy-invited__about">
Expand Down
4 changes: 2 additions & 2 deletions app/views/projects/_screenshot.html.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<%# locals: (project:) %>
<%# A screenshot of your game: pick one and it uploads; click it again to replace it. %>
<% saved = project.screenshot.attached? && project.screenshot.blob.persisted? %>
<% saved = project.stored_screenshot %>
<%= form_with model: project, url: project_path, method: :patch, multipart: true, class: "project__shot",
data: { controller: "project-screenshot" } do |form| %>
<label class="project__shot-slot" <%= "data-filled" if saved %>>
<% if saved %>
<%= image_tag url_for(project.screenshot), alt: "Screenshot of #{project.title}", class: "project__shot-image" %>
<%= image_tag url_for(saved), alt: "Screenshot of #{project.title}", class: "project__shot-image" %>
<span class="project__shot-replace">Replace screenshot</span>
<% else %>
<span class="project__shot-placeholder">Add a screenshot</span>
Expand Down
2 changes: 1 addition & 1 deletion app/views/ships/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</div>
</main>
<% else %>
<% screenshot = @project.screenshot if @project.screenshot.attached? && @project.screenshot.blob.persisted? %>
<% screenshot = @project.stored_screenshot %>
<%= form_with model: @ship, url: project_ship_path, method: :post, multipart: true, class: "ship__form",
data: { controller: "ship", ship_description_min_value: Ship::DESCRIPTION_MIN, ship_has_screenshot_value: screenshot.present?,
action: "input->ship#check change->ship#check" } do |form| %>
Expand Down
7 changes: 7 additions & 0 deletions test/controllers/projects_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,13 @@ class ProjectsControllerTest < ActionDispatch::IntegrationTest
assert_select ".project__shot-image[alt='Screenshot of Beat Sheet']"
get leaderboard_path
assert_select "tr[data-you] .leaderboard__shot"

blob = projects(:orpheus).reload.screenshot.blob
blob.service.delete(blob.key)
get leaderboard_path
assert_select "tr[data-you] .leaderboard__shot", count: 0
get project_path
assert_select ".project__shot-placeholder", "Add a screenshot"
end

test "a screenshot that isn't an image says so" do
Expand Down
11 changes: 11 additions & 0 deletions test/models/project_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ class ProjectTest < ActiveSupport::TestCase
assert project.valid?
end

test "a screenshot whose file has gone from storage isn't shown" do
project = projects(:orpheus)
project.screenshot.attach(io: file_fixture("screenshot.png").open, filename: "screenshot.png", content_type: "image/png")
project.save!
assert_equal project.screenshot, project.stored_screenshot

project.screenshot.blob.service.delete(project.screenshot.blob.key)
assert project.screenshot.attached?
assert_nil project.reload.stored_screenshot
end

test "the ticked Hackatime projects are the linked ones, and new ones have to be on Hackatime" do
project = projects(:orpheus)
link_hackatime(project.user)
Expand Down
Loading