Skip to content

Commit

Permalink
Merge pull request #266 from minnestar/multiday-events
Browse files Browse the repository at this point in the history
Multiday events + more controlled schedule preview
  • Loading branch information
pcantrell committed Oct 1, 2020
2 parents 8e70f79 + 513f4c9 commit ee9f1c3
Show file tree
Hide file tree
Showing 24 changed files with 112 additions and 64 deletions.
5 changes: 5 additions & 0 deletions src/app/assets/stylesheets/schedule.css.sass
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
margin-left: 1em
font-weight: normal
color: rgba(255, 255, 255, 0.75)
h3
font:
family: 'Helvetica Neue', 'Verdana', sans-serif
size: 1.4em !important
padding: 0.8em 1em

.sessions
clear: both
Expand Down
10 changes: 1 addition & 9 deletions src/app/controllers/admin/admin_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Admin::AdminController < ApplicationController
before_action :redirect_to_ssl
before_action :authenticate
before_action :authenticate # in ApplicationController

private

Expand All @@ -10,12 +10,4 @@ def redirect_to_ssl
end
end

def authenticate
if Rails.env.production?
authenticate_or_request_with_http_basic do |user_name, password|
user_name == ENV['SESSIONIZER_ADMIN_USER'] && password == ENV['SESSIONIZER_ADMIN_PASSWORD']
end
end
end

end
4 changes: 0 additions & 4 deletions src/app/controllers/admin_controller.rb

This file was deleted.

17 changes: 17 additions & 0 deletions src/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ def verify_session
end
end

def event_from_params(includes: {})
query_base = Event.includes(**includes)
if params[:event_id].blank? || params[:event_id] == 'current'
query_base.current_event
else
query_base.includes(**includes).find(params[:event_id])
end
end

def event_schedule_cache_key(event)
[
event,
Expand All @@ -39,4 +48,12 @@ def event_schedule_cache_key(event)
]
end
helper_method :event_schedule_cache_key

def authenticate
if Rails.env.production?
authenticate_or_request_with_http_basic do |user_name, password|
user_name == ENV['SESSIONIZER_ADMIN_USER'] && password == ENV['SESSIONIZER_ADMIN_PASSWORD']
end
end
end
end
40 changes: 29 additions & 11 deletions src/app/controllers/schedules_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
class SchedulesController < ApplicationController

before_action :authenticate, if: -> { params[:preview] }

def index
unless Settings.show_schedule? || params[:force]
if !event || schedule_hidden?
redirect_to home_page_path
return
end
@event = Event.current_event
render layout: 'schedule'
end

Expand Down Expand Up @@ -55,20 +57,36 @@ def ical
end

def event_timeslots
@event_timeslots ||= load_event.timeslots
@event_timeslots ||= event.timeslots
end
helper_method :event_timeslots

private

def load_event
event = Event.includes(timeslots: { sessions: [:room, :presenters] }).find(Event.current_event.id)
def header_timeslots
@header_timeslots ||= if @event.multiday?
@event.first_timeslots_of_day
else
event_timeslots.where(schedulable: true)
end
end
helper_method :header_timeslots

def event
@event ||= begin
event = event_from_params(includes: { timeslots: { sessions: [:room, :presenters] } })

if event
# Preload vote counts in order to sort sessions by popularity
Session.preload_attendance_counts(
event.timeslots.map(&:sessions).flatten)
end

# Preload vote counts in order to sort sessions by popularity
Session.preload_attendance_counts(
event.timeslots.map(&:sessions).flatten)
event
end
end
helper_method :event

event
def schedule_hidden?
event.current? && !Settings.show_schedule? && !params[:preview]
end

end
6 changes: 1 addition & 5 deletions src/app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ def destroy
end

def index
if params[:event_id].blank? || params[:event_id] == 'current'
@event = Event.current_event
else
@event = Event.find(params[:event_id])
end
@event = event_from_params

respond_to do |format|
format.json do
Expand Down
4 changes: 2 additions & 2 deletions src/app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def add_sessions_button
end
end

def toggle_attendance_button(session)
if session.event.current?
def toggle_attendance_button(event, session)
if event.current?
content_tag(:button, "Attending", class: "toggle-attendance", 'data-session-id': session.id)
end
end
Expand Down
6 changes: 5 additions & 1 deletion src/app/helpers/schedules_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
module SchedulesHelper

def pill_label(slot)
slot.starts_at.in_time_zone.to_s(:usahhmm)
if slot.event.multiday?
slot.date_range.start_day
else
slot.date_range.start_time
end
end

def session_columns_for_slot(slot, &block)
Expand Down
22 changes: 20 additions & 2 deletions src/app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Event < ActiveRecord::Base

validates_presence_of :name, :date

def self.current_event(opts = {})
Event.order(:date).last
def self.current_event
self.order(:date).last
end

def current?
Expand All @@ -21,4 +21,22 @@ def current?
end
@current
end

def multiday?
if @multiday.nil?
separate_day_count = timeslots.map(&:starts_at).map(&:midnight).uniq.count
@multiday = separate_day_count > 1
end
@multiday
end

# The list of timeslots that are at the first of each day of the event
def first_timeslots_of_day
@first_timeslots_of_day ||= begin
timeslots
.group_by { |slot| slot.starts_at.midnight }
.map { |date, slots| slots.sort_by(&:starts_at).first }
.sort_by(&:starts_at)
end
end
end
2 changes: 1 addition & 1 deletion src/app/models/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Session < ActiveRecord::Base

scope :recent, -> { order('created_at desc') }

scope :random_order, -> { order('random()') }
scope :random_order, -> { order(Arel.sql('random()')) }

validates_presence_of :description
validates_presence_of :event_id
Expand Down
6 changes: 4 additions & 2 deletions src/app/models/timeslot.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

class Timeslot < ActiveRecord::Base
belongs_to :event
has_many :sessions, dependent: :nullify
Expand Down Expand Up @@ -25,11 +27,11 @@ def initialize(start, stop)
end

def to_s(with_day: false)
"#{start_day + ' ' if with_day}#{start_time}#{end_time}"
"#{start_day + ' ' if with_day}#{start_time}#{end_time}"
end

def start_day
start.in_time_zone.strftime('%a')
start.in_time_zone.strftime('%a, %b %e')
end

def start_time
Expand Down
2 changes: 1 addition & 1 deletion src/app/views/admin/configs/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<li class="boolean">
<%= label_tag do %>
<%= check_box_tag :show_schedule, 'true', settings.show_schedule? %>
Display sessions on the front page
Display schedule to the public
<% end %>
</li>
</ol>
Expand Down
2 changes: 1 addition & 1 deletion src/app/views/events/_aside.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<p><%= add_sessions_button %></p>

<div class="sidebar-box">
<%= markdown MarkdownContent.find_by_slug('homepage-summary').markdown, trusted: true %>
<%= markdown MarkdownContent.find_by_slug('homepage-summary')&.markdown, trusted: true %>
</div>
</div>
2 changes: 1 addition & 1 deletion src/app/views/layouts/schedule.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<%= csrf_meta_tags %>
<title><%= @event.name %> &ndash; Session Schedule</title>
<title><%= event.name %> &ndash; Session Schedule</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= favicon_link_tag 'favicon.ico' %>
Expand Down
2 changes: 1 addition & 1 deletion src/app/views/schedules/_header.html.haml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.nav-top
.timeslots
- event_timeslots.where(schedulable: true).each do |slot|
- header_timeslots.each do |slot|
%a.timeslot{:id => "timeslot_#{slot.id}_nav",
:href=> "#timeslot_#{slot.id}",
:startsAt => slot.starts_at.in_time_zone.to_i,
Expand Down
4 changes: 2 additions & 2 deletions src/app/views/schedules/index.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- cache [current_participant.nil?] + event_schedule_cache_key(@event), expires_in: 10.minutes do
- cache [current_participant.nil?] + event_schedule_cache_key(event), expires_in: 10.minutes do
= render 'header'
.schedule
.schedule-header
Expand All @@ -7,7 +7,7 @@
%a#show-all(href='#') Show all details
.clr
%h1
= @event.name
= event.name
Session Schedule
- if current_participant.nil?
%p
Expand Down
2 changes: 1 addition & 1 deletion src/app/views/sessions/_session.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<li>
<%= toggle_attendance_button(session) %>
<%= toggle_attendance_button(@event, session) %>
<h4><%= link_to session.title, session %></h4>
<div class="presenter">by <%= session.presenters.map {|p| link_to p.name, p }.to_sentence.html_safe %></div>
<% edit(session) do %>
Expand Down
2 changes: 1 addition & 1 deletion src/app/views/sessions/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<% if @session.timeslot && Settings.show_schedule? %>
|
<b><%= @session.timeslot.date_range.to_s(with_day: false) %></b>
<b><%= @session.timeslot.date_range.to_s(with_day: @session.event.multiday?) %></b>
<% if @session.room %>
in <b><%= @session.room.name %></b>
<% end %>
Expand Down
18 changes: 12 additions & 6 deletions src/app/views/timeslots/_timeslot.html.haml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
.timeslot{ id: "timeslot_#{timeslot.id}" }
%h2
.time
= timeslot.date_range.to_s(with_day: false)
.title
= timeslot.title

- if event.multiday?
- if event.first_timeslots_of_day.include?(timeslot)
%h2
.time= timeslot.date_range.start_day
%h3
.time= timeslot.date_range.to_s(with_day: false)
- else
%h2
.time= timeslot.date_range.to_s(with_day: false)
.title= timeslot.title

- if timeslot.sessions.present?
.sessions
Expand All @@ -13,7 +19,7 @@

.session
.header
= toggle_attendance_button(session)
= toggle_attendance_button(event, session)
- if session.room
- map_location = asset_path("maps/#{session.room.name.downcase}.png")
.room{:href => "#{map_location}" }
Expand Down
1 change: 1 addition & 0 deletions src/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Session actions available for all events
resources :events, :only => [:show] do
resources :sessions, :only => [:index]
get '/schedule' => 'schedules#index'
end

# Session actions available only for the current event
Expand Down
2 changes: 2 additions & 0 deletions src/lib/tasks/app.rake
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

namespace :app do

desc 'create default timeslots for the most recent event'
Expand Down
11 changes: 0 additions & 11 deletions src/spec/controllers/admin_controller_spec.rb

This file was deleted.

2 changes: 1 addition & 1 deletion src/spec/controllers/schedules_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

context "when schedules are not yet displayed, but they really want to see it anyway" do
it "is successful" do
get :index, params: {force: true}
get :index, params: {preview: true}
expect(response).to be_successful
expect(assigns[:event]).to eq event
expect(response.body).to match(session.title)
Expand Down
4 changes: 3 additions & 1 deletion src/spec/models/timeslot_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

require 'spec_helper'

describe Timeslot do
Expand All @@ -21,7 +23,7 @@

context "when with_day is set" do
subject { timeslot.to_s(with_day: true) }
it { is_expected.to eq 'Sun 9:00 – 9:50 Session 1' }
it { is_expected.to eq 'Sun, Sep 13 • 9:00 – 9:50 Session 1' }
end

context "no args" do
Expand Down

0 comments on commit ee9f1c3

Please sign in to comment.