3980e9651e
Reviewed-on: #357 Co-authored-by: miteruzo <miteruzo@naver.com> Co-committed-by: miteruzo <miteruzo@naver.com>
160 行
4.7 KiB
Ruby
160 行
4.7 KiB
Ruby
class TheatresController < ApplicationController
|
|
def show
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
|
|
render json: TheatreRepr.base(theatre)
|
|
end
|
|
|
|
def watching
|
|
return head :unauthorized unless current_user
|
|
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
|
|
host_flg = false
|
|
post_id = nil
|
|
post_started_at = nil
|
|
|
|
theatre.with_lock do
|
|
TheatreWatchingUser.find_or_initialize_by(theatre:, user: current_user).tap {
|
|
_1.expires_at = 30.seconds.from_now
|
|
}.save!
|
|
|
|
if (!(theatre.host_user_id?) ||
|
|
!(theatre.watching_users.exists?(id: theatre.host_user_id)))
|
|
theatre.update!(host_user_id: current_user.id)
|
|
end
|
|
|
|
host_flg = theatre.host_user_id == current_user.id
|
|
post_id = theatre.current_post_id
|
|
post_started_at = theatre.current_post_started_at
|
|
end
|
|
|
|
render json: theatre_info_json(theatre, host_flg:, post_id:, post_started_at:)
|
|
end
|
|
|
|
def next_post
|
|
return head :unauthorized unless current_user
|
|
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
return head :forbidden if theatre.host_user != current_user
|
|
|
|
ApplicationRecord.transaction do
|
|
theatre.lock!
|
|
TheatrePostAdvancer.call(theatre:)
|
|
end
|
|
|
|
head :no_content
|
|
end
|
|
|
|
def skip_vote
|
|
return head :unauthorized unless current_user
|
|
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
requested_post_id = params[:post_id].to_i
|
|
return head :unprocessable_entity if requested_post_id <= 0
|
|
|
|
skipped = false
|
|
conflicted = false
|
|
|
|
ApplicationRecord.transaction do
|
|
theatre.lock!
|
|
if theatre.current_post
|
|
TheatreWatchingUser.find_or_initialize_by(theatre:, user: current_user).tap {
|
|
_1.expires_at = 30.seconds.from_now
|
|
}.save!
|
|
|
|
if theatre.current_post_id != requested_post_id
|
|
conflicted = true
|
|
next
|
|
end
|
|
|
|
TheatreSkipVote.find_or_create_by!(theatre:, post_id: requested_post_id, user: current_user)
|
|
|
|
vote_status = skip_vote_status(theatre)
|
|
if vote_status[:votes_count] >= vote_status[:required_count]
|
|
TheatreSkipFinalizer.call(theatre:, user: current_user)
|
|
TheatrePostAdvancer.call(theatre:)
|
|
skipped = true
|
|
end
|
|
end
|
|
end
|
|
|
|
theatre.reload
|
|
return render json: theatre_info_json(theatre, skipped: false), status: :conflict if conflicted
|
|
|
|
render json: theatre_info_json(theatre, skipped:)
|
|
end
|
|
|
|
def unskip_vote
|
|
return head :unauthorized unless current_user
|
|
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
requested_post_id = params[:post_id].to_i
|
|
return head :unprocessable_entity if requested_post_id <= 0
|
|
|
|
conflicted = false
|
|
|
|
theatre.with_lock do
|
|
if theatre.current_post
|
|
if theatre.current_post_id != requested_post_id
|
|
conflicted = true
|
|
else
|
|
TheatreSkipVote.where(theatre:, post_id: requested_post_id, user: current_user).delete_all
|
|
end
|
|
end
|
|
end
|
|
|
|
theatre.reload
|
|
return render json: theatre_info_json(theatre, skipped: false), status: :conflict if conflicted
|
|
|
|
render json: theatre_info_json(theatre, skipped: false)
|
|
end
|
|
|
|
def post_selection_weights
|
|
theatre = Theatre.find_by(id: params[:id])
|
|
return head :not_found unless theatre
|
|
|
|
render json: TheatrePostSelector.new(theatre:).weight_json
|
|
end
|
|
|
|
private
|
|
|
|
def theatre_info_json(theatre, host_flg: nil, post_id: nil, post_started_at: nil, skipped: nil)
|
|
host_flg = theatre.host_user_id == current_user&.id if host_flg.nil?
|
|
post_id = theatre.current_post_id if post_id.nil?
|
|
post_started_at = theatre.current_post_started_at if post_started_at.nil?
|
|
|
|
json = { host_flg:,
|
|
post_id:,
|
|
post_started_at:,
|
|
post_elapsed_ms: post_started_at ? ((Time.current - post_started_at) * 1000).floor : nil,
|
|
watching_users: theatre.watching_users.as_json(only: [:id, :name]),
|
|
skip_vote: skip_vote_status(theatre) }
|
|
json[:skipped] = skipped unless skipped.nil?
|
|
json
|
|
end
|
|
|
|
def skip_vote_status(theatre)
|
|
watching_user_ids = theatre.watching_users.ids
|
|
watching_users_count = watching_user_ids.size
|
|
required_count = (watching_users_count / 2) + 1
|
|
post = theatre.current_post
|
|
votes =
|
|
if post
|
|
TheatreSkipVote.where(theatre:, post:, user_id: watching_user_ids)
|
|
else
|
|
TheatreSkipVote.none
|
|
end
|
|
|
|
{ votes_count: post ? votes.count : 0,
|
|
required_count:,
|
|
watching_users_count:,
|
|
voted: post && current_user ? votes.exists?(user_id: current_user.id) : false }
|
|
end
|
|
end
|