Skip to content

Commit

Permalink
Optimize contribution page (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienpoly authored Dec 19, 2024
1 parent b61d35c commit a800e9b
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 227 deletions.
9 changes: 8 additions & 1 deletion .erb_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ linters:
enabled: true
PartialInstanceVariable:
enabled: true

exclude:
- app/views/contributions/_events_without_videos.html.erb
- app/views/contributions/_speakers_without_github.html.erb
- app/views/contributions/_talks_without_slides.html.erb
- app/views/contributions/_events_without_location.html.erb
- app/views/contributions/_events_without_dates.html.erb
- app/views/contributions/_talks_dates_out_of_bounds.html.erb
- app/views/contributions/_missing_videos_cue.html.erb
Rubocop:
enabled: true
rubocop_config:
Expand Down
104 changes: 70 additions & 34 deletions app/controllers/contributions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,70 @@
class ContributionsController < ApplicationController
include Turbo::ForceFrameResponse
force_frame_response only: %i[show]
skip_before_action :authenticate_user!, only: %i[index]

STEPS = %i[speakers_without_github talks_without_slides events_without_videos
events_without_location events_without_dates talks_dates_out_of_bounds missing_videos_cue].freeze

def index
# Overdue scheduled talks

@overdue_scheduled_talks = Talk.where(video_provider: "scheduled").where("date < ?", Date.today).order(date: :asc)
@overdue_scheduled_talks_count = @overdue_scheduled_talks.count

# Not published talks

@not_published_talks = Talk.where(video_provider: "not_published").order(date: :desc)
@not_published_talks_count = @not_published_talks.count

# Talks without speakers

@talks_without_speakers = Speaker.find_by(name: "TODO").talks
@talks_without_speakers_count = @talks_without_speakers.count

# Missing events

conference_names = Event.all.pluck(:name)
@upstream_conferences = begin
RubyConferences::Client.new.conferences_cached.reverse
rescue
[]
end
@pending_conferences = @upstream_conferences.reject { |conference| conference["name"].in?(conference_names) }

@with_video_link, @without_video_link = @pending_conferences.partition { |conference| conference["video_link"].present? }

@conferences_to_index = @with_video_link.count + @without_video_link.count
@already_index_conferences = @upstream_conferences.count - @conferences_to_index

# Conferences with missing schedules
@conferences_with_missing_schedule = Event.joins(:organisation).where(organisation: {kind: :conference}).reject { |event| event.schedule.exist? }.group_by(&:organisation)
@conferences_with_missing_schedule_count = @conferences_with_missing_schedule.flat_map(&:last).count
end

def show
@step = params[:step].to_sym.presence_in(STEPS)

if @step
send(@step)
else
raise StandardError, "missing step"
end
end

def speakers_without_github
speaker_ids_with_pending_github_suggestions = Suggestion.pending.where("json_extract(content, '$.github') IS NOT NULL").where(suggestable_type: "Speaker").pluck(:suggestable_id)
@speakers_without_github = Speaker.canonical.without_github.order(talks_count: :desc).where.not(id: speaker_ids_with_pending_github_suggestions)
@speakers_without_github_count = @speakers_without_github.count
end

def talks_without_slides
speakers_with_speakerdeck = Speaker.where.not(speakerdeck: "")
@talks_without_slides = Talk.preload(:speakers).joins(:speakers).where(slides_url: nil).where(speakers: {id: speakers_with_speakerdeck}).order(date: :desc)
@talks_without_slides_count = @talks_without_slides.count
end

def events_without_videos
@events_without_videos = Event.includes(:organisation).left_joins(:talks).where(talks_count: 0).group_by(&:organisation)
@events_without_videos_count = @events_without_videos.flat_map(&:last).count

Expand All @@ -18,9 +73,19 @@ def index

@events_without_dates = Static::Playlist.where(start_date: nil).group_by(&:__file_path)
@events_without_dates_count = @events_without_dates.flat_map(&:last).count
end

# Review Talk Dates
def events_without_location
@events_without_location = Static::Playlist.where(location: nil).group_by(&:__file_path)
@events_without_location_count = @events_without_location.flat_map(&:last).count
end

def events_without_dates
@events_without_dates = Static::Playlist.where(start_date: nil).group_by(&:__file_path)
@events_without_dates_count = @events_without_dates.flat_map(&:last).count
end

def talks_dates_out_of_bounds
events_with_start_date = Static::Playlist.all.pluck(:title, :start_date, :end_date).select { |_, start_date| start_date.present? }
events_without_start_date = Static::Playlist.all.pluck(:title, :year, :start_date).select { |_, _, start_date, _| start_date.blank? }

Expand All @@ -33,41 +98,12 @@ def index

@out_of_bound_talks = talks_by_event_name.map { |event, talks| [event, talks.reject { |talk| @dates_by_event_name[event.name].cover?(talk.date) }] }
@out_of_bound_talks_count = @out_of_bound_talks.map(&:last).flatten.count
end

# Overdue scheduled talks

@overdue_scheduled_talks = Talk.where(video_provider: "scheduled").where("date < ?", Date.today).order(date: :asc)
@overdue_scheduled_talks_count = @overdue_scheduled_talks.count

# Not published talks

@not_published_talks = Talk.where(video_provider: "not_published").order(date: :desc)
@not_published_talks_count = @not_published_talks.count

# Talks without speakers

@talks_without_speakers = Speaker.find_by(name: "TODO").talks
@talks_without_speakers_count = @talks_without_speakers.count

# Missing events

conference_names = Event.all.pluck(:name)
@upstream_conferences = RubyConferences::Client.new.conferences_cached.reverse
@pending_conferences = @upstream_conferences.reject { |conference| conference["name"].in?(conference_names) }

@with_video_link, @without_video_link = @pending_conferences.partition { |conference| conference["video_link"].present? }

@conferences_to_index = @with_video_link.count + @without_video_link.count
@already_index_conferences = @upstream_conferences.count - @conferences_to_index

# Missing video cues

def missing_videos_cue
videos_with_missing_cues = Static::Video.all.select { |video| video.talks.any? { |t| t.start_cue == "TODO" || t.end_cue == "TODO" } }
@missing_videos_cue = videos_with_missing_cues.map { |video| Talk.find_by(video_provider: video.video_provider || :youtube, video_id: video.video_id) }.compact&.group_by(&:event)&.select { |_event, talks| talks.any? } || []
videos_with_missing_cues_ids = videos_with_missing_cues.map(&:video_id)
@missing_videos_cue = Talk.includes(:child_talks, :event).where(video_id: videos_with_missing_cues_ids).group_by(&:event)&.select { |_event, talks| talks.any? } || []
@missing_videos_cue_count = videos_with_missing_cues.count

# Conferences with missing schedules
@conferences_with_missing_schedule = Event.joins(:organisation).where(organisation: {kind: :conference}).reject { |event| event.schedule.exist? }.group_by(&:organisation)
@conferences_with_missing_schedule_count = @conferences_with_missing_schedule.flat_map(&:last).count
end
end
21 changes: 21 additions & 0 deletions app/views/contributions/_events_without_dates.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%= turbo_frame_tag "events_without_dates" do %>
<h2 class="mb-4">Events without conference dates (<%= @events_without_dates_count %>)</h2>

<article class="prose mb-6">This section lists events that are missing conference dates. Adding conference dates allows us to show when this event took place, so we could show them in a calendar or similar.</article>

<div id="events-without-dates" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6">
<% @events_without_dates.each do |file_path, events| %>
<%= link_to "https://github.com/adrienpoly/rubyvideo/edit/main/#{file_path}", id: "event-#{file_path}", class: "hover:bg-gray-100 p-4 rounded-lg border bg-white", target: :_blank do %>
<div class="flex flex-col">
<h3 class="line-clamp-1"><pre>Data File: <%= file_path %></pre></h3>

<b class="mt-4 mb-2">Events missing dates:</b>

<% events.each do |event| %>
<span><%= event.title %></span>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
21 changes: 21 additions & 0 deletions app/views/contributions/_events_without_location.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%= turbo_frame_tag "events_without_location" do %>
<h2 class="mb-4">Events without locations (<%= @events_without_location_count %>)</h2>

<article class="prose mb-6">This section lists events that are missing location information. By adding a location, we can show in which city/country this event took place.</article>

<div id="events-without-locations" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6">
<% @events_without_location.each do |file_path, events| %>
<%= link_to "https://github.com/adrienpoly/rubyvideo/edit/main/#{file_path}", id: "event-#{file_path}", class: "hover:bg-gray-100 p-4 rounded-lg border bg-white", target: :_blank do %>
<div class="flex flex-col">
<h3 class="line-clamp-1"><pre>Data File: <%= file_path %></pre></h3>

<b class="mt-4 mb-2">Events missing locations:</b>

<% events.each do |event| %>
<span><%= event.title %></span>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
21 changes: 21 additions & 0 deletions app/views/contributions/_events_without_videos.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%= turbo_frame_tag "events_without_videos" do %>
<h2 class="mb-4">Events without videos (<%= @events_without_videos_count %>)</h2>

<article class="prose mb-6">This section highlights events that do not have associated videos available. Explore these events to see if the talks weren't recorded or just not yet added the site.</article>

<div id="events-without-locations" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6">
<% @events_without_videos.each do |organisation, events| %>
<%= content_tag :div, id: dom_id(organisation, "without-videos"), class: "p-4 rounded-lg border bg-white", target: :_blank do %>
<div class="flex flex-col">
<h3 class="line-clamp-1"><p>Organisation: <%= link_to organisation.name, organisation, class: "hover:underline" %></p></h3>

<b class="mt-4 mb-2">Events without videos:</b>

<% events.each do |event| %>
<span><%= link_to event.name, event, class: "hover:underline" %></span>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
19 changes: 19 additions & 0 deletions app/views/contributions/_introduction.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<article class="prose">
<h2>Welcome to RubyVideo.dev! 🌟</h2>

<p>We are thrilled to have you here and appreciate your interest in making this resource the best it can be for the community. If you would like to lend a hand, there are various ways you can contribute.</p>

<p>This page serves as a friendly starting point for anyone looking to get involved but unsure where to begin. Here are some ways you can help:</p>

<ul>
<li>Assist in adding missing GitHub handles to speakers</li>
<li>Help identify speakers based on conference screenshots</li>
<li>Contribute by adding last names to speakers</li>
<li>Attach Slides to talks</li>
<li>Review the date when the talk was given</li>
<li>Add location information to conferences</li>
<li>Add event dates to conferences</li>
<li>Add data for new conferences</li>
</ul>
</article>
</div>
25 changes: 25 additions & 0 deletions app/views/contributions/_missing_videos_cue.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<%= turbo_frame_tag "missing_videos_cue" do %>
<h2 class="mb-4">Missing Video Cues (<%= @missing_videos_cue_count %>)</h2>

<article class="prose mb-6">
This section highlights talks that have child talks but are missing video cues. You can help by adding video cues to these talks so we can let users play the the talk from the exact time it starts.
</article>

<div id="talks-dates-out-of-bounds" class="grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6">
<% @missing_videos_cue.each do |event, talks| %>
<%= content_tag :div, id: dom_id(event), class: "p-4 rounded-lg border bg-white", target: :_blank do %>
<article class="prose">
<h3 class="line-clamp-1">Event: <%= event.name %></h3>

<b class="mt-4 mb-2">Recording doesn't have cues for it's child talks:</b>

<ul>
<% talks.each do |talk| %>
<li><%= link_to talk.title, talk %> (<%= link_to pluralize(talk.child_talks.size, "talk"), talk %>) [<%= link_to "Data File", "https://github.com/adrienpoly/rubyvideo/edit/main/#{talk.static_metadata.__file_path}", target: :_blank %>]</li>
<% end %>
</ul>
</article>
<% end %>
<% end %>
</div>
<% end %>
26 changes: 26 additions & 0 deletions app/views/contributions/_speakers_without_github.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<%= turbo_frame_tag "speakers_without_github" do %>
<h2 class="mb-4">Speakers without GitHub handles (<%= @speakers_without_github_count %>)</h2>

<article class="prose mb-6">These speakers are currently missing a GitHub handle. By adding a GitHub handle to their profile, we can enhance their speaker profiles with an avatar and automatically retrieve additional information.</article>

<div id="speakers" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 min-w-full mb-6">
<% @speakers_without_github.each do |speaker| %>
<%= content_tag :div, id: dom_id(speaker), class: "flex justify-between p-4 rounded-lg border bg-white" do %>
<span><%= link_to speaker.name, edit_speaker_path(speaker), class: "underline link", data: {turbo_frame: "modal"} %></span>
<span>
<%= link_to "https://github.com/search?q=#{speaker.name}&type=users", target: "_blank", class: "underline link" do %>
<%= heroicon "magnifying-glass", variant: :outline, class: "size-5" %>
<% end %>
</span>
<% end %>
<% end %>

<% remaining_speakers_count = (@speakers_without_github_count - @speakers_without_github.count) %>

<% if remaining_speakers_count.positive? %>
<div class="flex items-center hover:bg-gray-100 p-4 rounded-lg border bg-white">
<span>and <%= remaining_speakers_count %> more</span>
</div>
<% end %>
</div>
<% end %>
25 changes: 25 additions & 0 deletions app/views/contributions/_talks_dates_out_of_bounds.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<%= turbo_frame_tag "talks_dates_out_of_bounds" do %>
<h2 class="mb-4">Review Talk Dates (<%= @out_of_bound_talks_count %>)</h2>

<article class="prose mb-6">This section shows talks with dates that don't quite match the event dates. Sometimes we only have the year for certain events, so we use that as a reference.</article>

<div id="talks-dates-out-of-bounds" class="grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6">
<% @out_of_bound_talks.select { |_event, talks| talks.any? }.each do |event, talks| %>
<%= content_tag :div, id: dom_id(event), class: "p-4 rounded-lg border bg-white", target: :_blank do %>
<article class="prose">
<h3 class="line-clamp-1">Event: <%= event.name %></h3>

<b class="mt-4 mb-2">Talk date is outside event dates:</b>

<p class="mb-2">Event Dates: <%= @dates_by_event_name[event.name].inspect %></p>

<ul>
<% talks.each do |talk| %>
<li><%= link_to talk.title, talk %> (<%= link_to talk.date.to_fs(:long), talk %>)</li>
<% end %>
</ul>
</article>
<% end %>
<% end %>
</div>
<% end %>
24 changes: 24 additions & 0 deletions app/views/contributions/_talks_without_slides.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<%= turbo_frame_tag "talks_without_slides" do %>
<h2 class="mb-4">Talks without slides (<%= @talks_without_slides_count %>)</h2>

<article class="prose mb-6">These talks currently do not have slides attached. However, we know that the speaker has an account on Speakerdeck where they usually upload their slides. Feel free to explore if these talks have associated slidedecks on Speakerdeck.com.</article>

<div id="speakers" class="grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6">
<% @talks_without_slides.each do |talk| %>
<%= link_to edit_talk_path(talk), id: dom_id(talk), class: "hover:bg-gray-100 p-4 rounded-lg border bg-white" do %>
<div class="flex flex-col">
<span class="font-bold"><%= talk.title %></span>
<span><%= talk.speakers.first.name %></span>
</div>
<% end %>
<% end %>

<% remaining_talks_count = (@talks_without_slides_count - @talks_without_slides.count) %>

<% if remaining_talks_count.positive? %>
<div class="flex items-center hover:bg-gray-100 p-4 rounded-lg border bg-white">
<span>and <%= remaining_talks_count %> more</span>
</div>
<% end %>
</div>
<% end %>
Loading

0 comments on commit a800e9b

Please sign in to comment.