add support for embed blocks, with some styling for youtube

This commit is contained in:
2024-07-15 00:24:28 +02:00
parent 55f8062f07
commit 55257f3bb4
14 changed files with 244 additions and 27 deletions

View File

@ -56,7 +56,10 @@ export default async function Page({ params }: { params: { slug: string } }) {
</p>
<h1 className="news-title">{news.title}</h1>
{news.lead && (
<div className="lead" dangerouslySetInnerHTML={{ __html: news.lead }} />
<div
className="lead"
dangerouslySetInnerHTML={{ __html: news.lead }}
/>
)}
{featuredImage && (
<ImageFigure

View File

@ -4,6 +4,7 @@ import { ImageSliderBlock } from "./ImageSliderBlock";
import { HorizontalRuleBlock } from "./HorizontalRuleBlock";
import { FeaturedBlock } from "./FeaturedBlock";
import { AccordionBlock } from "./AccordionBlock";
import { EmbedBlock } from "./EmbedBlock";
import { FactBoxBlock } from "./FactBoxBlock";
import { PageSectionBlock, PageSectionNavigationBlock } from "./PageSection";
import { ContactSectionBlock, ContactSubsectionBlock } from "./ContactSection";
@ -14,17 +15,20 @@ import { OpeningHoursSectionBlock } from "./OpeningHoursSectionBlock";
export const Blocks = ({ blocks }: any) => {
const sections = blocks.filter(
(block: any) => block.__typename === "PageSectionBlock"
(block: any) => block?.__typename === "PageSectionBlock"
);
return blocks.map((block: any) => {
switch (block.blockType) {
switch (block?.blockType) {
case "RichTextBlock":
return <RichTextBlock block={block} />;
break;
case "ImageWithTextBlock":
return <ImageWithTextBlock block={block} />;
break;
case "EmbedBlock":
return <EmbedBlock block={block} />;
break;
case "ImageSliderBlock":
return <ImageSliderBlock block={block} />;
break;
@ -65,8 +69,8 @@ export const Blocks = ({ blocks }: any) => {
return <OpeningHoursSectionBlock />;
break;
default:
return <div>Unsupported block type {block.blockType}</div>;
console.log("unsupported block", block);
return <div>Unsupported block type {block?.blockType}</div>;
}
});
};

View File

@ -0,0 +1,39 @@
import { EmbedBlock as EmbedBlockType } from "@/gql/graphql";
import styles from "./embedBlock.module.scss";
export const EmbedBlock = ({ block }: { block: EmbedBlockType }) => {
if (!block.embed) {
return <></>;
}
/* YouTube rawEmbed example
{
title: "EEEAAAOOO",
type: "video",
thumbnail_url: "https://i.ytimg.com/vi/v1K4EAXe2oo/hqdefault.jpg",
width: 200,
height: 113,
html: '<iframe width="200" height="113" src="https://www.youtube.com/embed/v1K4EAXe2oo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="EEEAAAOOO"></iframe>',
};
*/
let embedData: any = {};
try {
embedData = JSON.parse(block.rawEmbed);
} catch (e) {
embedData = {};
}
const { width, height } = embedData;
const aspectRatio = width && height ? width / height : null;
return (
<div
className={styles.embed}
dangerouslySetInnerHTML={{ __html: block.embed }}
data-type={embedData?.type ?? ""}
style={
aspectRatio
? ({ "--aspect-ratio": aspectRatio } as React.CSSProperties)
: {}
}
></div>
);
};

View File

@ -0,0 +1,9 @@
.embed {
&[data-type="video"] {
iframe {
width: 100%;
height: auto;
aspect-ratio: var(--aspect-ratio)
}
}
}

View File

@ -36,7 +36,7 @@ const documents = {
"\n query home {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\n }\n }\n }\n ": types.HomeDocument,
"\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.VenueRentalIndexFragmentDoc,
"\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\") {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n ": types.VenueRentalIndexDocument,
"\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n }\n": types.OneLevelOfBlocksFragmentDoc,
"\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n ... on EmbedBlock {\n url\n embed\n rawEmbed\n }\n }\n": types.OneLevelOfBlocksFragmentDoc,
"\n fragment Blocks on StreamFieldInterface {\n ... on AccordionBlock {\n heading\n body {\n ...OneLevelOfBlocks\n }\n }\n ... on FactBoxBlock {\n heading\n backgroundColor\n body {\n ...OneLevelOfBlocks\n }\n }\n ... on PageSectionBlock {\n title\n backgroundColor\n body {\n ...OneLevelOfBlocks\n }\n }\n ... on ContactSectionBlock {\n title\n text\n blocks {\n ... on ContactSubsectionBlock {\n title\n text\n blocks {\n ...OneLevelOfBlocks\n }\n }\n ...OneLevelOfBlocks\n }\n }\n ...OneLevelOfBlocks\n }\n": types.BlocksFragmentDoc,
"\n fragment Image on CustomImage {\n id\n url\n width\n height\n alt\n attribution\n }\n": types.ImageFragmentDoc,
"\n fragment ContactEntity on ContactEntity {\n id\n name\n contactType\n title\n email\n phoneNumber\n image {\n ...Image\n }\n }\n": types.ContactEntityFragmentDoc,
@ -160,7 +160,7 @@ export function graphql(source: "\n query venueRentalIndex {\n index: ve
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n }\n"): (typeof documents)["\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n }\n"];
export function graphql(source: "\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n ... on EmbedBlock {\n url\n embed\n rawEmbed\n }\n }\n"): (typeof documents)["\n fragment OneLevelOfBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n ... on EmbedBlock {\n url\n embed\n rawEmbed\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

File diff suppressed because one or more lines are too long

View File

@ -126,6 +126,11 @@ const OneLevelOfBlocksFragmentDefinition = graphql(`
}
}
}
... on EmbedBlock {
url
embed
rawEmbed
}
}
`);