Pages now use the new ThumbnailPreview component

This commit is contained in:
DrMint 2022-04-23 20:32:55 +02:00
parent 351c526dbe
commit 81ac3fb23a
8 changed files with 212 additions and 29 deletions

View File

@ -21,9 +21,8 @@ export default function RecorderChip(props: Props): JSX.Element {
{recorder.avatar?.data?.attributes && ( {recorder.avatar?.data?.attributes && (
<Img <Img
className="w-20 rounded-full border-4 border-mid" className="w-20 rounded-full border-4 border-mid"
image={recorder.avatar?.data.attributes} image={recorder.avatar.data.attributes}
quality={ImageQuality.Small} quality={ImageQuality.Small}
rawImg
/> />
)} )}
<div className="grid gap-2"> <div className="grid gap-2">

View File

@ -7,7 +7,8 @@ import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import VideoPreview from "components/Videos/VideoPreview"; import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { GetVideoChannelQuery } from "graphql/generated"; import { GetVideoChannelQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { import {
@ -16,6 +17,8 @@ import {
GetStaticPropsContext, GetStaticPropsContext,
} from "next"; } from "next";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { getVideoThumbnailURL } from "queries/helpers";
import { useState } from "react";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
channel: Exclude< channel: Exclude<
@ -26,6 +29,8 @@ interface Props extends AppStaticProps {
export default function Channel(props: Props): JSX.Element { export default function Channel(props: Props): JSX.Element {
const { langui, channel } = props; const { langui, channel } = props;
const [keepInfoVisible, setKeepInfoVisible] = useState(true);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ReturnButton <ReturnButton
@ -41,6 +46,11 @@ export default function Channel(props: Props): JSX.Element {
title="Videos" title="Videos"
description={langui.archives_description} description={langui.archives_description}
/> />
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel> </SubPanel>
); );
@ -52,7 +62,28 @@ export default function Channel(props: Props): JSX.Element {
</div> </div>
<div className="grid gap-8 items-start mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0"> <div className="grid gap-8 items-start mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0">
{channel?.videos?.data.map((video) => ( {channel?.videos?.data.map((video) => (
<>{video.attributes && <VideoPreview video={video.attributes} />}</> <>
{video.attributes && (
<ThumbnailPreview
key={video.id}
href={`/archives/videos/v/${video.attributes.uid}`}
title={video.attributes.title}
thumbnail={getVideoThumbnailURL(video.attributes.uid)}
thumbnailAspectRatio="16/9"
keepInfoVisible={keepInfoVisible}
metadata={{
release_date: video.attributes.published_date,
views: video.attributes.views,
author: channel.title,
position: "Top",
}}
hoverlay={{
__typename: "Video",
duration: video.attributes.duration,
}}
/>
)}
</>
))} ))}
</div> </div>
</ContentPanel> </ContentPanel>

View File

@ -8,12 +8,13 @@ import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import VideoPreview from "components/Videos/VideoPreview"; import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { GetVideosPreviewQuery } from "graphql/generated"; import { GetVideosPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettyDate } from "queries/helpers"; import { getVideoThumbnailURL, prettyDate } from "queries/helpers";
import { useState } from "react"; import { useState } from "react";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
@ -44,6 +45,7 @@ export default function Videos(props: Props): JSX.Element {
} }
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const [keepInfoVisible, setKeepInfoVisible] = useState(true);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
@ -60,6 +62,11 @@ export default function Videos(props: Props): JSX.Element {
title="Videos" title="Videos"
description={langui.archives_description} description={langui.archives_description}
/> />
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel> </SubPanel>
); );
@ -76,7 +83,24 @@ export default function Videos(props: Props): JSX.Element {
{paginatedVideos[page].map((video) => ( {paginatedVideos[page].map((video) => (
<> <>
{video.attributes && ( {video.attributes && (
<VideoPreview key={video.id} video={video.attributes} /> <ThumbnailPreview
key={video.id}
href={`/archives/videos/v/${video.attributes.uid}`}
title={video.attributes.title}
thumbnail={getVideoThumbnailURL(video.attributes.uid)}
thumbnailAspectRatio="16/9"
keepInfoVisible={keepInfoVisible}
metadata={{
release_date: video.attributes.published_date,
views: video.attributes.views,
author: video.attributes.channel?.data?.attributes?.title,
position: "Top",
}}
hoverlay={{
__typename: "Video",
duration: video.attributes.duration,
}}
/>
)} )}
</> </>
))} ))}

View File

@ -1,7 +1,7 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import Button from "components/Button"; import Button from "components/Button";
import Chip from "components/Chip"; import Chip from "components/Chip";
import ThumbnailHeader from "components/Content/ThumbnailHeader"; import ThumbnailHeader from "components/ThumbnailHeader";
import HorizontalLine from "components/HorizontalLine"; import HorizontalLine from "components/HorizontalLine";
import LanguageSwitcher from "components/LanguageSwitcher"; import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn"; import Markdawn from "components/Markdown/Markdawn";

View File

@ -1,12 +1,13 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import Chip from "components/Chip"; import Chip from "components/Chip";
import LibraryContentPreview from "components/Library/LibraryContentPreview";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import ContentPanel, { import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import Select from "components/Select"; import Select from "components/Select";
import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { GetContentsQuery } from "graphql/generated"; import { GetContentsQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
@ -24,6 +25,7 @@ export default function Contents(props: Props): JSX.Element {
const { langui, contents } = props; const { langui, contents } = props;
const [groupingMethod, setGroupingMethod] = useState<number>(-1); const [groupingMethod, setGroupingMethod] = useState<number>(-1);
const [keepInfoVisible, setKeepInfoVisible] = useState(false);
const [groups, setGroups] = useState<GroupContentItems>( const [groups, setGroups] = useState<GroupContentItems>(
getGroups(langui, groupingMethod, contents) getGroups(langui, groupingMethod, contents)
@ -51,6 +53,11 @@ export default function Contents(props: Props): JSX.Element {
allowEmpty allowEmpty
/> />
</div> </div>
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel> </SubPanel>
); );
const contentPanel = ( const contentPanel = (
@ -79,9 +86,33 @@ export default function Contents(props: Props): JSX.Element {
{items.map((item) => ( {items.map((item) => (
<> <>
{item.attributes && ( {item.attributes && (
<LibraryContentPreview <ThumbnailPreview
key={item.id} key={item.id}
item={item.attributes} href={`/contents/${item.attributes.slug}`}
pre_title={item.attributes.titles?.[0]?.pre_title}
title={
item.attributes.titles?.[0]?.title ??
prettySlug(item.attributes.slug)
}
subtitle={item.attributes.titles?.[0]?.subtitle}
thumbnail={item.attributes.thumbnail?.data?.attributes}
thumbnailAspectRatio="3/2"
topChips={
item.attributes.type?.data?.attributes
? [
item.attributes.type.data.attributes.titles?.[0]
? item.attributes.type.data.attributes
.titles[0]?.title
: prettySlug(
item.attributes.type.data.attributes.slug
),
]
: undefined
}
bottomChips={item.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)}
keepInfoVisible={keepInfoVisible}
/> />
)} )}
</> </>

View File

@ -3,8 +3,7 @@ import Button from "components/Button";
import Chip from "components/Chip"; import Chip from "components/Chip";
import Img, { getAssetURL, ImageQuality } from "components/Img"; import Img, { getAssetURL, ImageQuality } from "components/Img";
import InsetBox from "components/InsetBox"; import InsetBox from "components/InsetBox";
import ContentTOCLine from "components/Library/ContentTOCLine"; import ContentLine from "components/Library/ContentLine";
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
import LightBox from "components/LightBox"; import LightBox from "components/LightBox";
import NavOption from "components/PanelComponents/NavOption"; import NavOption from "components/PanelComponents/NavOption";
import ReturnButton, { import ReturnButton, {
@ -14,6 +13,8 @@ import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { import {
Enum_Componentmetadatabooks_Binding_Type, Enum_Componentmetadatabooks_Binding_Type,
@ -68,6 +69,8 @@ export default function LibrarySlug(props: Props): JSX.Element {
const [lightboxImages, setLightboxImages] = useState([""]); const [lightboxImages, setLightboxImages] = useState([""]);
const [lightboxIndex, setLightboxIndex] = useState(0); const [lightboxIndex, setLightboxIndex] = useState(0);
const [keepInfoVisible, setKeepInfoVisible] = useState(false);
let displayOpenScans = false; let displayOpenScans = false;
if (item?.contents?.data) if (item?.contents?.data)
for (const content of item.contents.data) { for (const content of item.contents.data) {
@ -424,13 +427,42 @@ export default function LibrarySlug(props: Props): JSX.Element {
<h2 className="text-2xl"> <h2 className="text-2xl">
{isVariantSet ? langui.variants : langui.subitems} {isVariantSet ? langui.variants : langui.subitems}
</h2> </h2>
<div className="-mt-6 mb-8 flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
<div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full"> <div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
{item.subitems.data.map((subitem) => ( {item.subitems.data.map((subitem) => (
<LibraryItemsPreview <>
key={subitem.id} {subitem.attributes && (
item={subitem.attributes} <ThumbnailPreview
currencies={props.currencies} key={subitem.id}
/> href={`/library/${subitem.attributes.slug}`}
title={subitem.attributes.title}
subtitle={subitem.attributes.subtitle}
thumbnail={subitem.attributes.thumbnail?.data?.attributes}
thumbnailAspectRatio="21/29.7"
keepInfoVisible={keepInfoVisible}
topChips={
subitem.attributes.metadata &&
subitem.attributes.metadata.length > 0 &&
subitem.attributes.metadata[0]
? [prettyItemSubType(subitem.attributes.metadata[0])]
: []
}
bottomChips={subitem.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)}
metadata={{
currencies: currencies,
release_date: subitem.attributes.release_date,
price: subitem.attributes.price,
position: "Bottom",
}}
/>
)}
</>
))} ))}
</div> </div>
</div> </div>
@ -446,7 +478,7 @@ export default function LibrarySlug(props: Props): JSX.Element {
)} )}
<div className="grid gap-4 w-full"> <div className="grid gap-4 w-full">
{item.contents.data.map((content) => ( {item.contents.data.map((content) => (
<ContentTOCLine <ContentLine
langui={langui} langui={langui}
content={content} content={content}
parentSlug={item.slug} parentSlug={item.slug}

View File

@ -1,6 +1,5 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import Chip from "components/Chip"; import Chip from "components/Chip";
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import ContentPanel, { import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
@ -8,11 +7,17 @@ import ContentPanel, {
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import Select from "components/Select"; import Select from "components/Select";
import Switch from "components/Switch"; import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { GetLibraryItemsPreviewQuery } from "graphql/generated"; import { GetLibraryItemsPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { convertPrice, prettyDate, prettyinlineTitle } from "queries/helpers"; import {
convertPrice,
prettyDate,
prettyinlineTitle,
prettyItemSubType,
} from "queries/helpers";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
@ -32,6 +37,7 @@ export default function Library(props: Props): JSX.Element {
const [showSecondaryItems, setShowSecondaryItems] = useState<boolean>(false); const [showSecondaryItems, setShowSecondaryItems] = useState<boolean>(false);
const [sortingMethod, setSortingMethod] = useState<number>(0); const [sortingMethod, setSortingMethod] = useState<number>(0);
const [groupingMethod, setGroupingMethod] = useState<number>(-1); const [groupingMethod, setGroupingMethod] = useState<number>(-1);
const [keepInfoVisible, setKeepInfoVisible] = useState(false);
const [filteredItems, setFilteredItems] = useState<Props["items"]>( const [filteredItems, setFilteredItems] = useState<Props["items"]>(
filterItems( filterItems(
@ -120,6 +126,11 @@ export default function Library(props: Props): JSX.Element {
<p className="flex-shrink-0">{langui.show_secondary_items}:</p> <p className="flex-shrink-0">{langui.show_secondary_items}:</p>
<Switch state={showSecondaryItems} setState={setShowSecondaryItems} /> <Switch state={showSecondaryItems} setState={setShowSecondaryItems} />
</div> </div>
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel> </SubPanel>
); );
const contentPanel = ( const contentPanel = (
@ -146,11 +157,35 @@ export default function Library(props: Props): JSX.Element {
className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0" className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0"
> >
{items.map((item) => ( {items.map((item) => (
<LibraryItemsPreview <>
key={item.id} {item.attributes && (
item={item.attributes} <ThumbnailPreview
currencies={props.currencies} key={item.id}
/> href={`/library/${item.attributes.slug}`}
title={item.attributes.title}
subtitle={item.attributes.subtitle}
thumbnail={item.attributes.thumbnail?.data?.attributes}
thumbnailAspectRatio="21/29.7"
keepInfoVisible={keepInfoVisible}
topChips={
item.attributes.metadata &&
item.attributes.metadata.length > 0 &&
item.attributes.metadata[0]
? [prettyItemSubType(item.attributes.metadata[0])]
: []
}
bottomChips={item.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)}
metadata={{
currencies: currencies,
release_date: item.attributes.release_date,
price: item.attributes.price,
position: "Bottom",
}}
/>
)}
</>
))} ))}
</div> </div>
</> </>

View File

@ -1,15 +1,17 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import PostsPreview from "components/News/PostsPreview";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import ContentPanel, { import ContentPanel, {
ContentPanelWidthSizes, ContentPanelWidthSizes,
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import Switch from "components/Switch";
import ThumbnailPreview from "components/ThumbnailPreview";
import { GetPostsPreviewQuery } from "graphql/generated"; import { GetPostsPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettyDate } from "queries/helpers"; import { prettyDate, prettySlug } from "queries/helpers";
import { useState } from "react";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
posts: Exclude<GetPostsPreviewQuery["posts"], null | undefined>["data"]; posts: Exclude<GetPostsPreviewQuery["posts"], null | undefined>["data"];
@ -18,6 +20,8 @@ interface Props extends AppStaticProps {
export default function News(props: Props): JSX.Element { export default function News(props: Props): JSX.Element {
const { langui, posts } = props; const { langui, posts } = props;
const [keepInfoVisible, setKeepInfoVisible] = useState(true);
posts posts
.sort((a, b) => { .sort((a, b) => {
const dateA = a.attributes?.date ? prettyDate(a.attributes.date) : "9999"; const dateA = a.attributes?.date ? prettyDate(a.attributes.date) : "9999";
@ -33,6 +37,11 @@ export default function News(props: Props): JSX.Element {
title={langui.news} title={langui.news}
description={langui.news_description} description={langui.news_description}
/> />
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{"Always show info"}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel> </SubPanel>
); );
@ -40,7 +49,29 @@ export default function News(props: Props): JSX.Element {
<ContentPanel width={ContentPanelWidthSizes.large}> <ContentPanel width={ContentPanelWidthSizes.large}>
<div className="grid gap-8 items-end grid-cols-1 desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))]"> <div className="grid gap-8 items-end grid-cols-1 desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))]">
{posts.map((post) => ( {posts.map((post) => (
<PostsPreview key={post.id} post={post.attributes} /> <>
{post.attributes && (
<ThumbnailPreview
key={post.id}
href={`/news/${post.attributes.slug}`}
title={
post.attributes.translations?.[0]?.title ??
prettySlug(post.attributes.slug)
}
description={post.attributes.translations?.[0]?.excerpt}
thumbnail={post.attributes.thumbnail?.data?.attributes}
bottomChips={post.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)}
thumbnailAspectRatio="3/2"
keepInfoVisible={keepInfoVisible}
metadata={{
release_date: post.attributes.date,
position: "Top",
}}
/>
)}
</>
))} ))}
</div> </div>
</ContentPanel> </ContentPanel>