feat(voiceover): add description and spoiler fields to voice scripts
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
eecedece6b
commit
92117374b7
8 changed files with 46535 additions and 2 deletions
|
|
@ -6,7 +6,7 @@ export const VoiceScripts: CollectionConfig = {
|
|||
admin: {
|
||||
group: "Voiceover",
|
||||
useAsTitle: "title",
|
||||
defaultColumns: ["title", "xpAmount", "status", "createdAt"],
|
||||
defaultColumns: ["title", "xpAmount", "spoiler", "status", "createdAt"],
|
||||
},
|
||||
access: {
|
||||
read: ({ req }) => Boolean(req.user),
|
||||
|
|
@ -20,6 +20,15 @@ export const VoiceScripts: CollectionConfig = {
|
|||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
label: "Context Description",
|
||||
type: "textarea",
|
||||
admin: {
|
||||
description:
|
||||
"Optional context for readers: who is speaking, where this line happens, and anything else they should know before recording.",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "script",
|
||||
type: "textarea",
|
||||
|
|
@ -40,6 +49,16 @@ export const VoiceScripts: CollectionConfig = {
|
|||
description: "XP awarded per accepted submission of this script.",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "spoiler",
|
||||
label: "Potential Campaign Spoilers",
|
||||
type: "checkbox",
|
||||
defaultValue: false,
|
||||
admin: {
|
||||
description:
|
||||
"Warns readers on the frontend that this script may include, infer, or expose campaign spoilers.",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
type: "select",
|
||||
|
|
|
|||
|
|
@ -12,9 +12,11 @@ export interface VoiceoverSubmissionSummary {
|
|||
export interface VoiceoverScriptView {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string | null;
|
||||
script: string;
|
||||
xpAmount: number;
|
||||
status: string;
|
||||
spoiler: boolean;
|
||||
createdAt: string;
|
||||
/** This user's own submissions on the script, newest first. */
|
||||
mySubmissions: VoiceoverSubmissionSummary[];
|
||||
|
|
@ -59,9 +61,11 @@ function buildScriptView(
|
|||
return {
|
||||
id: script.id,
|
||||
title: script.title,
|
||||
description: script.description ?? null,
|
||||
script: script.script,
|
||||
xpAmount: script.xpAmount,
|
||||
status: script.status,
|
||||
spoiler: script.spoiler ?? false,
|
||||
createdAt: script.createdAt,
|
||||
mySubmissions,
|
||||
otherSubmissionCount,
|
||||
|
|
|
|||
23230
src/migrations/20260907_041051_add_voice_script_spoiler.json
Normal file
23230
src/migrations/20260907_041051_add_voice_script_spoiler.json
Normal file
File diff suppressed because it is too large
Load diff
11
src/migrations/20260907_041051_add_voice_script_spoiler.ts
Normal file
11
src/migrations/20260907_041051_add_voice_script_spoiler.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "voice_scripts" ADD COLUMN "spoiler" boolean DEFAULT false;`)
|
||||
}
|
||||
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "voice_scripts" DROP COLUMN "spoiler";`)
|
||||
}
|
||||
23236
src/migrations/20260907_043339_add_voice_script_description.json
Normal file
23236
src/migrations/20260907_043339_add_voice_script_description.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "voice_scripts" ADD COLUMN "description" varchar;`)
|
||||
}
|
||||
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
ALTER TABLE "voice_scripts" DROP COLUMN "description";`)
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@ import * as migration_20260906_165837_add_market_state_event_target from './2026
|
|||
import * as migration_20260906_202925_add_voice_submissions from './20260906_202925_add_voice_submissions';
|
||||
import * as migration_20260907_012326_add_missions_created_by from './20260907_012326_add_missions_created_by';
|
||||
import * as migration_20260907_013724_make_missions_campaign_optional from './20260907_013724_make_missions_campaign_optional';
|
||||
import * as migration_20260907_041051_add_voice_script_spoiler from './20260907_041051_add_voice_script_spoiler';
|
||||
import * as migration_20260907_043339_add_voice_script_description from './20260907_043339_add_voice_script_description';
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
|
|
@ -232,6 +234,16 @@ export const migrations = [
|
|||
{
|
||||
up: migration_20260907_013724_make_missions_campaign_optional.up,
|
||||
down: migration_20260907_013724_make_missions_campaign_optional.down,
|
||||
name: '20260907_013724_make_missions_campaign_optional'
|
||||
name: '20260907_013724_make_missions_campaign_optional',
|
||||
},
|
||||
{
|
||||
up: migration_20260907_041051_add_voice_script_spoiler.up,
|
||||
down: migration_20260907_041051_add_voice_script_spoiler.down,
|
||||
name: '20260907_041051_add_voice_script_spoiler',
|
||||
},
|
||||
{
|
||||
up: migration_20260907_043339_add_voice_script_description.up,
|
||||
down: migration_20260907_043339_add_voice_script_description.down,
|
||||
name: '20260907_043339_add_voice_script_description'
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -3092,6 +3092,10 @@ export interface MarketState {
|
|||
export interface VoiceScript {
|
||||
id: number;
|
||||
title: string;
|
||||
/**
|
||||
* Optional context for readers: who is speaking, where this line happens, and anything else they should know before recording.
|
||||
*/
|
||||
description?: string | null;
|
||||
/**
|
||||
* Voice talent reads this verbatim. Inline emotion tags like [calm] are stored as written.
|
||||
*/
|
||||
|
|
@ -3100,6 +3104,10 @@ export interface VoiceScript {
|
|||
* XP awarded per accepted submission of this script.
|
||||
*/
|
||||
xpAmount: number;
|
||||
/**
|
||||
* Warns readers on the frontend that this script may include, infer, or expose campaign spoilers.
|
||||
*/
|
||||
spoiler?: boolean | null;
|
||||
/**
|
||||
* Closed scripts reject new submissions
|
||||
*/
|
||||
|
|
@ -5207,8 +5215,10 @@ export interface MarketStateSelect<T extends boolean = true> {
|
|||
*/
|
||||
export interface VoiceScriptsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
description?: T;
|
||||
script?: T;
|
||||
xpAmount?: T;
|
||||
spoiler?: T;
|
||||
status?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
|
|
|
|||
Loading…
Reference in a new issue