Support for scene break blocks

This commit is contained in:
DrMint 2024-03-15 21:20:34 +01:00
parent d64010e77c
commit f02aac1b22
6 changed files with 123 additions and 6 deletions

View File

@ -4,12 +4,13 @@
- [Payload] Fix SDK endpoint not working in prod - [Payload] Fix SDK endpoint not working in prod
- [Folder] Add parent pages - [Folder] Add parent pages
- Support for scene break blocks
- Add hover/active styling for settings options in topbar + language override - Add hover/active styling for settings options in topbar + language override
- Highlight currently selected language option in language override tooltip - Highlight currently selected language option in language override tooltip
- Save cookies for longer than just the session
## Mid term ## Mid term
- Support for nameless section
- [Collectibles] Create page for gallery - [Collectibles] Create page for gallery
- [Collectibles] Create page for scans - [Collectibles] Create page for scans
- When the tags overflow, the tag group name should be align start (see http://localhost:12499/en/pages/magnitude-negative-chapter-1) - When the tags overflow, the tag group name should be align start (see http://localhost:12499/en/pages/magnitude-negative-chapter-1)
@ -29,3 +30,8 @@
- Global search function - Global search function
- Convert Rich text to simple text for indexing and open graph purposes - Convert Rich text to simple text for indexing and open graph purposes
- Anonymous comments - Anonymous comments
## Bonus
- Static HTML site export for archival
- Secret Terminal mode

View File

@ -3,11 +3,13 @@ import type { RichTextContext } from "src/utils/richText";
import RTSection from "./components/RTSection.astro"; import RTSection from "./components/RTSection.astro";
import RTTranscript from "./components/RTTranscript.astro"; import RTTranscript from "./components/RTTranscript.astro";
import { import {
isBlockNodeBreakBlock,
isBlockNodeSectionBlock, isBlockNodeSectionBlock,
isBlockNodeTranscriptBlock, isBlockNodeTranscriptBlock,
type RichTextBlockNode, type RichTextBlockNode,
} from "src/shared/payload/payload-sdk"; } from "src/shared/payload/payload-sdk";
import ErrorMessage from "components/ErrorMessage.astro"; import ErrorMessage from "components/ErrorMessage.astro";
import RTBreak from "./components/RTBreak.astro";
interface Props { interface Props {
node: RichTextBlockNode; node: RichTextBlockNode;
@ -22,6 +24,8 @@ const { node, context } = Astro.props;
<RTSection node={node} context={context} /> <RTSection node={node} context={context} />
) : isBlockNodeTranscriptBlock(node) ? ( ) : isBlockNodeTranscriptBlock(node) ? (
<RTTranscript node={node} context={context} /> <RTTranscript node={node} context={context} />
) : isBlockNodeBreakBlock(node) ? (
<RTBreak node={node} context={context} />
) : ( ) : (
<ErrorMessage <ErrorMessage
title={`Unknown block type: ${node.fields.blockType}`} title={`Unknown block type: ${node.fields.blockType}`}

View File

@ -0,0 +1,61 @@
---
import type { RichTextContext } from "src/utils/richText";
import { BreakBlockType, type RichTextBreakBlock } from "src/shared/payload/payload-sdk";
import ErrorMessage from "components/ErrorMessage.astro";
interface Props {
node: RichTextBreakBlock;
context: RichTextContext;
}
const { node } = Astro.props;
---
{
node.fields.type === BreakBlockType.space ? (
<>
<br />
<br />
<br />
<br />
<br />
</>
) : node.fields.type === BreakBlockType.sceneBreak ? (
<p>***</p>
) : node.fields.type === BreakBlockType.dottedLine ? (
<hr class="dotted" />
) : node.fields.type === BreakBlockType.solidLine ? (
<hr class="solid" />
) : (
<ErrorMessage
title={`Unknown break block type: ${node.fields.type}`}
description="Please contact website technical administrator."
/>
)
}
<style>
p {
margin-block: 4rem;
text-align: center;
font-size: 2em;
color: var(--color-base-600);
letter-spacing: 1em;
}
hr {
border: none;
border-top-color: var(--color-base-500);
width: 100%;
margin-block: 4rem;
&.dotted {
border-top-style: dotted;
border-top-width: 3px;
}
&.solid {
border-top-style: solid;
border-top-width: 1px;
}
}
</style>

View File

@ -1,4 +1,5 @@
--- ---
import { getI18n } from "src/i18n/i18n";
import type { TableOfContentEntry } from "src/shared/payload/payload-sdk"; import type { TableOfContentEntry } from "src/shared/payload/payload-sdk";
interface Props { interface Props {
@ -6,12 +7,28 @@ interface Props {
} }
const { entry } = Astro.props; const { entry } = Astro.props;
const { t } = await getI18n(Astro.locals.currentLocale);
const title = (() => {
switch (entry.type) {
case "sceneBreak":
return entry.title || t("pages.tableOfContent.sceneBreak", { index: entry.index });
case "break":
return entry.title || t("pages.tableOfContent.break", { index: entry.index });
case "section":
default:
return entry.title;
}
})();
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<li data-prefix={entry.prefix}> <li data-prefix={entry.prefix}>
<a href={`#${entry.prefix}`} class="pressable-link table-of-content-item">{entry.title}</a> <a href={`#${entry.prefix}`} class="pressable-link table-of-content-item">{title}</a>
{ {
entry.children.length > 0 && ( entry.children.length > 0 && (
<ol> <ol>

View File

@ -84,4 +84,6 @@ export type WordingKey =
| "header.nav.parentPages.collections.collectible" | "header.nav.parentPages.collections.collectible"
| "header.nav.parentPages.tooltip" | "header.nav.parentPages.tooltip"
| "global.meta.description" | "global.meta.description"
| "global.loading"; | "global.loading"
| "pages.tableOfContent.sceneBreak"
| "pages.tableOfContent.break";

View File

@ -795,12 +795,22 @@ export interface CueBlock {
}; };
blockType: 'cueBlock'; blockType: 'cueBlock';
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "BreakBlock".
*/
export interface BreakBlock {
type: 'Scene break' | 'Empty space' | 'Solid line' | 'Dotted line';
id?: string | null;
blockName?: string | null;
blockType: 'breakBlock';
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "TranscriptBlock". * via the `definition` "TranscriptBlock".
*/ */
export interface TranscriptBlock { export interface TranscriptBlock {
lines: (LineBlock | CueBlock)[]; lines: (LineBlock | CueBlock | BreakBlock)[];
id?: string | null; id?: string | null;
blockName?: string | null; blockName?: string | null;
blockType: 'transcriptBlock'; blockType: 'transcriptBlock';
@ -874,6 +884,13 @@ export enum LanguageCodes {
"zh" = "Chinese", "zh" = "Chinese",
} }
export enum BreakBlockType {
sceneBreak = "Scene break",
space = "Empty space",
solidLine = "Solid line",
dottedLine = "Dotted line",
}
export enum CollectibleBindingTypes { export enum CollectibleBindingTypes {
Paperback = "Paperback", Paperback = "Paperback",
Hardcover = "Hardcover", Hardcover = "Hardcover",
@ -1031,6 +1048,10 @@ export interface RichTextTranscriptBlock extends RichTextBlockNode {
fields: TranscriptBlock; fields: TranscriptBlock;
} }
export interface RichTextBreakBlock extends RichTextBlockNode {
fields: BreakBlock;
}
export const isNodeParagraphNode = (node: RichTextNode): node is RichTextParagraphNode => export const isNodeParagraphNode = (node: RichTextNode): node is RichTextParagraphNode =>
node.type === "paragraph"; node.type === "paragraph";
@ -1080,19 +1101,22 @@ export const isBlockNodeTranscriptBlock = (
node: RichTextBlockNode node: RichTextBlockNode
): node is RichTextTranscriptBlock => node.fields.blockType === "transcriptBlock"; ): node is RichTextTranscriptBlock => node.fields.blockType === "transcriptBlock";
export const isBlockNodeBreakBlock = (node: RichTextBlockNode): node is RichTextBreakBlock =>
node.fields.blockType === "breakBlock";
/* BLOCKS */ /* BLOCKS */
/* TODO: TO BE REMOVED WHEN https://github.com/payloadcms/payload/issues/5216 is closed */ /* TODO: TO BE REMOVED WHEN https://github.com/payloadcms/payload/issues/5216 is closed */
export interface CueBlock { export interface CueBlock {
content: RichTextContent; content: RichTextContent;
blockType: 'cueBlock'; blockType: "cueBlock";
id?: string | null; id?: string | null;
blockName?: string | null; blockName?: string | null;
} }
export interface LineBlock { export interface LineBlock {
content: RichTextContent; content: RichTextContent;
blockType: 'lineBlock'; blockType: "lineBlock";
id?: string | null; id?: string | null;
blockName?: string | null; blockName?: string | null;
} }
@ -1109,6 +1133,7 @@ export const isBlockCueBlock = (block: GenericBlock): block is CueBlock =>
export const isBlockLineBlock = (block: GenericBlock): block is LineBlock => export const isBlockLineBlock = (block: GenericBlock): block is LineBlock =>
block.blockType === "lineBlock"; block.blockType === "lineBlock";
////////////////// SDK ////////////////// ////////////////// SDK //////////////////
import NodeCache from "node-cache"; import NodeCache from "node-cache";
@ -1408,6 +1433,8 @@ export type EndpointCollectible = EndpointCollectiblePreview & {
export type TableOfContentEntry = { export type TableOfContentEntry = {
prefix: string; prefix: string;
title: string; title: string;
type: "sceneBreak" | "break" | "section";
index: number;
children: TableOfContentEntry[]; children: TableOfContentEntry[];
}; };