From 39d86f477821a974391e5edccad9b95781ac2add Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 7 Jun 2026 01:24:44 +0900 Subject: [PATCH] #302 --- .../theatre_skip_events_controller.rb | 6 +-- backend/app/services/theatre_post_selector.rb | 40 +++++++------------ backend/db/schema.rb | 1 - .../src/pages/theatres/TheatreDetailPage.tsx | 19 +++++++-- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/backend/app/controllers/theatre_skip_events_controller.rb b/backend/app/controllers/theatre_skip_events_controller.rb index 18ec914..fbbdae9 100644 --- a/backend/app/controllers/theatre_skip_events_controller.rb +++ b/backend/app/controllers/theatre_skip_events_controller.rb @@ -6,15 +6,15 @@ class TheatreSkipEventsController < ApplicationController events = TheatreSkipEvent .where(theatre_id: params[:theatre_id]) - .includes(:tags, post: { tags: :tag_name }) + .includes(: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), - tags: event.tags.map { |tag| TagRepr.inline(tag) }, + post: { id: event.post.id, title: event.post.title, url: event.post.url }, + tags: event.tags.map { |tag| { id: tag.id, name: tag.name } }, programme_position: event.programme_position, created_at: event.created_at } } diff --git a/backend/app/services/theatre_post_selector.rb b/backend/app/services/theatre_post_selector.rb index 2da5092..51efb84 100644 --- a/backend/app/services/theatre_post_selector.rb +++ b/backend/app/services/theatre_post_selector.rb @@ -24,11 +24,9 @@ class TheatrePostSelector candidates = weighted_candidates sorted = candidates.sort_by { |candidate| [candidate.weight, candidate.post.id] } - { - tag_penalties: tag_penalty_json, + { tag_penalties: tag_penalty_json, lightest_posts: post_weight_json(sorted.first(limit)), - heaviest_posts: post_weight_json(sorted.reverse.first(limit)) - } + heaviest_posts: post_weight_json(sorted.reverse.first(limit)) } end private @@ -45,11 +43,10 @@ class TheatrePostSelector penalty = post_tags.sum { |tag| penalties[tag.id].to_i } Candidate.new( - post:, - penalty:, - tags: post_tags, - weight: 1.0 / (1.0 + penalty) - ) + post:, + penalty:, + tags: post_tags, + weight: 1.0 / (1.0 + penalty)) end end end @@ -87,10 +84,8 @@ class TheatrePostSelector tag = tags[tag_id] next unless tag - { - tag: light_tag_json(tag), - penalty: - } + { tag: light_tag_json(tag), + penalty: } } .compact .sort_by { |row| [-row[:penalty], row[:tag][:name].to_s] } @@ -98,27 +93,22 @@ class TheatrePostSelector def post_weight_json candidates candidates.map { |candidate| - { - post: light_post_json(candidate.post), + { post: light_post_json(candidate.post), weight: candidate.weight, penalty: candidate.penalty, - tags: candidate.tags.map { |tag| light_tag_json(tag) } - } + tags: candidate.tags.map { |tag| light_tag_json(tag) } } } end def light_post_json post - { - id: post.id, + { id: post.id, title: post.title, - url: post.url - } + url: post.url } end def light_tag_json tag - { - id: tag.id, - name: tag.name - } + { id: tag.id, + name: tag.name, + category: tag.category } end end diff --git a/backend/db/schema.rb b/backend/db/schema.rb index b6fef2f..9fe2736 100644 --- a/backend/db/schema.rb +++ b/backend/db/schema.rb @@ -339,7 +339,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_06_06_000000) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["expires_at"], name: "index_theatre_watching_users_on_expires_at" - t.index ["theatre_id", "expires_at"], name: "idx_on_theatre_id_skip_expires_at_4c8de1dd42" t.index ["theatre_id", "expires_at"], name: "index_theatre_watching_users_on_theatre_id_and_expires_at" t.index ["theatre_id"], name: "index_theatre_watching_users_on_theatre_id" t.index ["user_id"], name: "index_theatre_watching_users_on_user_id" diff --git a/frontend/src/pages/theatres/TheatreDetailPage.tsx b/frontend/src/pages/theatres/TheatreDetailPage.tsx index df44f6f..e3e1fb3 100644 --- a/frontend/src/pages/theatres/TheatreDetailPage.tsx +++ b/frontend/src/pages/theatres/TheatreDetailPage.tsx @@ -22,6 +22,7 @@ import { useValidationErrors } from '@/lib/useValidationErrors' import type { FC, FormEvent, ReactNode } from 'react' import type { NiconicoMetadata, + NiconicoVideoInfo, NiconicoViewerHandle, Post, Category, @@ -459,6 +460,19 @@ const TheatreDetailPage: FC = ({ user }: Props) => { await advancePost () } + const handleNiconicoLoadComplete = (info: NiconicoVideoInfo) => { + const lengthMs = info.lengthInSeconds * 1_000 + setVideoLength (lengthMs) + + if (lengthMs <= 0) + { + void handlePlaybackError () + return + } + + embedRef.current?.play () + } + const handleSkipVote = async () => { if (!(id) || !(post)) return @@ -797,10 +811,7 @@ const TheatreDetailPage: FC = ({ user }: Props) => { key={post.id} ref={embedRef} post={post} - onLoadComplete={info => { - embedRef.current?.play () - setVideoLength (info.lengthInSeconds * 1_000) - }} + onLoadComplete={handleNiconicoLoadComplete} onMetadataChange={syncPlayback} onError={handlePlaybackError}/>) : (