このコミットが含まれているのは:
2026-06-06 19:49:21 +09:00
コミット 81e620c33a
22個のファイルの変更1290行の追加245行の削除
+3 -1
ファイルの表示
@@ -12,6 +12,8 @@ class TheatreProgrammesController < ApplicationController
.order(position: :desc).limit(100)
.limit(limit)
render json: programmes.as_json(include: { post: PostRepr::BASE })
render json: programmes.map { |programme|
programme.as_json.merge(post: PostRepr.base(programme.post))
}
end
end
+24
ファイルの表示
@@ -0,0 +1,24 @@
class TheatreSkipEventsController < ApplicationController
def index
limit = params[:limit].to_i
limit = 50 if limit <= 0
events =
TheatreSkipEvent
.where(theatre_id: params[:theatre_id])
.includes(:skipped_by_user, :users, :tags, post: { tags: :tag_name })
.order(created_at: :desc)
.limit(limit)
render json: events.map { |event|
{ id: event.id,
theatre_id: event.theatre_id,
post: PostRepr.base(event.post),
skipped_by_user: UserRepr.base(event.skipped_by_user),
voters: event.users.map { |user| UserRepr.base(user) },
tags: event.tags.map { |tag| TagRepr.inline(tag) },
programme_position: event.programme_position,
created_at: event.created_at }
}
end
end
+88 -9
ファイルの表示
@@ -31,9 +31,7 @@ class TheatresController < ApplicationController
post_started_at = theatre.current_post_started_at
end
render json: {
host_flg:, post_id:, post_started_at:,
watching_users: theatre.watching_users.as_json(only: [:id, :name]) }
render json: theatre_info_json(theatre, host_flg:, post_id:, post_started_at:)
end
def next_post
@@ -44,14 +42,95 @@ class TheatresController < ApplicationController
return head :forbidden if theatre.host_user != current_user
ApplicationRecord.transaction do
post = Post.where("url LIKE '%nicovideo.jp%'")
.order('RAND()')
.first
theatre.update!(current_post: post, current_post_started_at: Time.current)
position = (theatre.programmes.maximum(:position) || 0) + 1
theatre.programmes.create!(position:, post:)
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
skipped = 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!
TheatreSkipVote.find_or_create_by!(theatre:, post: theatre.current_post, 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
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
if theatre.current_post
TheatreSkipVote.where(theatre:, post: theatre.current_post, user: current_user).delete_all
end
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