このコミットが含まれているのは:
2026-06-07 01:24:44 +09:00
コミット 39d86f4778
4個のファイルの変更33行の追加33行の削除
+3 -3
ファイルの表示
@@ -6,15 +6,15 @@ class TheatreSkipEventsController < ApplicationController
events = events =
TheatreSkipEvent TheatreSkipEvent
.where(theatre_id: params[:theatre_id]) .where(theatre_id: params[:theatre_id])
.includes(:tags, post: { tags: :tag_name }) .includes(:post, tags: :tag_name)
.order(created_at: :desc) .order(created_at: :desc)
.limit(limit) .limit(limit)
render json: events.map { |event| render json: events.map { |event|
{ id: event.id, { id: event.id,
theatre_id: event.theatre_id, theatre_id: event.theatre_id,
post: PostRepr.base(event.post), post: { id: event.post.id, title: event.post.title, url: event.post.url },
tags: event.tags.map { |tag| TagRepr.inline(tag) }, tags: event.tags.map { |tag| { id: tag.id, name: tag.name } },
programme_position: event.programme_position, programme_position: event.programme_position,
created_at: event.created_at } created_at: event.created_at }
} }
+15 -25
ファイルの表示
@@ -24,11 +24,9 @@ class TheatrePostSelector
candidates = weighted_candidates candidates = weighted_candidates
sorted = candidates.sort_by { |candidate| [candidate.weight, candidate.post.id] } 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)), 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 end
private private
@@ -45,11 +43,10 @@ class TheatrePostSelector
penalty = post_tags.sum { |tag| penalties[tag.id].to_i } penalty = post_tags.sum { |tag| penalties[tag.id].to_i }
Candidate.new( Candidate.new(
post:, post:,
penalty:, penalty:,
tags: post_tags, tags: post_tags,
weight: 1.0 / (1.0 + penalty) weight: 1.0 / (1.0 + penalty))
)
end end
end end
end end
@@ -87,10 +84,8 @@ class TheatrePostSelector
tag = tags[tag_id] tag = tags[tag_id]
next unless tag next unless tag
{ { tag: light_tag_json(tag),
tag: light_tag_json(tag), penalty: }
penalty:
}
} }
.compact .compact
.sort_by { |row| [-row[:penalty], row[:tag][:name].to_s] } .sort_by { |row| [-row[:penalty], row[:tag][:name].to_s] }
@@ -98,27 +93,22 @@ class TheatrePostSelector
def post_weight_json candidates def post_weight_json candidates
candidates.map { |candidate| candidates.map { |candidate|
{ { post: light_post_json(candidate.post),
post: light_post_json(candidate.post),
weight: candidate.weight, weight: candidate.weight,
penalty: candidate.penalty, penalty: candidate.penalty,
tags: candidate.tags.map { |tag| light_tag_json(tag) } tags: candidate.tags.map { |tag| light_tag_json(tag) } }
}
} }
end end
def light_post_json post def light_post_json post
{ { id: post.id,
id: post.id,
title: post.title, title: post.title,
url: post.url url: post.url }
}
end end
def light_tag_json tag def light_tag_json tag
{ { id: tag.id,
id: tag.id, name: tag.name,
name: tag.name category: tag.category }
}
end end
end end
生成ファイル
-1
ファイルの表示
@@ -339,7 +339,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_06_06_000000) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["expires_at"], name: "index_theatre_watching_users_on_expires_at" 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", "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 ["theatre_id"], name: "index_theatre_watching_users_on_theatre_id"
t.index ["user_id"], name: "index_theatre_watching_users_on_user_id" t.index ["user_id"], name: "index_theatre_watching_users_on_user_id"
+15 -4
ファイルの表示
@@ -22,6 +22,7 @@ import { useValidationErrors } from '@/lib/useValidationErrors'
import type { FC, FormEvent, ReactNode } from 'react' import type { FC, FormEvent, ReactNode } from 'react'
import type { NiconicoMetadata, import type { NiconicoMetadata,
NiconicoVideoInfo,
NiconicoViewerHandle, NiconicoViewerHandle,
Post, Post,
Category, Category,
@@ -459,6 +460,19 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
await advancePost () 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 () => { const handleSkipVote = async () => {
if (!(id) || !(post)) if (!(id) || !(post))
return return
@@ -797,10 +811,7 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
key={post.id} key={post.id}
ref={embedRef} ref={embedRef}
post={post} post={post}
onLoadComplete={info => { onLoadComplete={handleNiconicoLoadComplete}
embedRef.current?.play ()
setVideoLength (info.lengthInSeconds * 1_000)
}}
onMetadataChange={syncPlayback} onMetadataChange={syncPlayback}
onError={handlePlaybackError}/>) : ( onError={handlePlaybackError}/>) : (
<div className="grid min-h-72 place-items-center text-zinc-400"> <div className="grid min-h-72 place-items-center text-zinc-400">