From 0e35f5aed91039febf2099f3cfb559c80acdd987 Mon Sep 17 00:00:00 2001 From: DrMint Date: Thu, 17 Feb 2022 02:49:32 +0100 Subject: [PATCH] Added support for touch screens where hovering is not possible --- src/components/AppLayout.tsx | 41 +++-- .../Library/LibraryContentPreview.tsx | 26 +-- .../Library/LibraryItemsPreview.tsx | 85 +++++---- src/graphql/operation.graphql | 161 ++++++++++++------ src/graphql/operations-types.ts | 94 ++++++++-- src/pages/library/items/[slug].tsx | 45 ++--- src/pages/library/items/index.tsx | 8 +- src/queries/helpers.ts | 46 ++++- src/tailwind.css | 4 +- tailwind.config.js | 8 +- 10 files changed, 367 insertions(+), 151 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index d1218f0..1f41794 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -22,12 +22,15 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { const subPanelClass = "fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:w-[20rem]"; let contentPanelClass = ""; + let turnSubIntoContent = false; if (props.subPanel && props.contentPanel) { contentPanelClass = "fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0"; } else if (props.contentPanel) { contentPanelClass = "fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:right-0"; + } else if (props.subPanel) { + turnSubIntoContent = true; } return ( @@ -52,7 +55,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { className="material-icons mt-[.1em] cursor-pointer" onClick={() => setsubPanelOpen(true)} > - {props.subPanel + {props.subPanel && !turnSubIntoContent ? props.subPanelIcon ? props.subPanelIcon : "tune" @@ -68,12 +71,21 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {props.contentPanel} ) : ( - "" +
+
+
+

+

Select one of the options in the sidebar

+
+
+
)} {/* Background when navbar is opened */}
- {/* Main panel */} -
- -
- {/* Sub panel */} {props.subPanel ? (
{props.subPanel}
) : ( "" )} + + {/* Main panel */} +
+ +
); } diff --git a/src/components/Library/LibraryContentPreview.tsx b/src/components/Library/LibraryContentPreview.tsx index a38415a..7486d85 100644 --- a/src/components/Library/LibraryContentPreview.tsx +++ b/src/components/Library/LibraryContentPreview.tsx @@ -21,10 +21,10 @@ export default function LibraryContentPreview( return ( -
+
{item.thumbnail.data ? ( {item.thumbnail.data.attributes.alternativeText}
)} -
+
+
+ {item.type ? ( + + {item.type.data.attributes.titles.length > 0 + ? item.type.data.attributes.titles[0].title + : prettySlug(item.type.data.attributes.slug)} + + ) : ( + "" + )} +
{item.titles.length > 0 ? ( <> @@ -45,20 +56,13 @@ export default function LibraryContentPreview(

{prettySlug(item.slug)}

)}
-
+
{item.categories.data.map((category) => ( {category.attributes.short} ))}
-
- {item.type ? ( - {item.type.data.attributes.titles.length > 0 ? item.type.data.attributes.titles[0].title : prettySlug(item.type.data.attributes.slug)} - ) : ( - "" - )} -
diff --git a/src/components/Library/LibraryItemsPreview.tsx b/src/components/Library/LibraryItemsPreview.tsx index 8bd4df5..7fcf31d 100644 --- a/src/components/Library/LibraryItemsPreview.tsx +++ b/src/components/Library/LibraryItemsPreview.tsx @@ -1,9 +1,20 @@ import Link from "next/link"; -import { GetLibraryItemsPreviewQuery } from "graphql/operations-types"; -import { getAssetURL, prettyDate, prettyPrice } from "queries/helpers"; +import { + GetLibraryItemsPreviewQuery, + GetWebsiteInterfaceQuery, +} from "graphql/operations-types"; +import { + getAssetURL, + prettyDate, + prettyPrice, + prettyItemSubType, +} from "queries/helpers"; import Image from "next/image"; +import Chip from "components/Chip"; export type LibraryItemsPreviewProps = { + className?: string; + langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; item: { slug: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["slug"]; thumbnail: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["thumbnail"]; @@ -11,6 +22,7 @@ export type LibraryItemsPreviewProps = { subtitle: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["subtitle"]; price?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"]; release_date?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"]; + metadata?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"]; }; }; @@ -18,10 +30,13 @@ export default function LibraryItemsPreview( props: LibraryItemsPreviewProps ): JSX.Element { const item = props.item; + const langui = props.langui; return ( -
+
{item.thumbnail.data ? (
)} -
+ +
+ {item.metadata && item.metadata.length > 0 ? ( +
+ {prettyItemSubType(item.metadata[0])} +
+ ) : ( + "" + )} +
-

{item.title}

-

{item.subtitle}

-
-
- {item.release_date ? ( -

- - event - - {prettyDate(item.release_date)} -

- ) : ( - "" - )} - {item.price ? ( -

- - shopping_cart - - {prettyPrice(item.price)} -

- ) : ( - "" - )} +

{item.title}

+

{item.subtitle}

+ {item.release_date || item.price ? ( +
+ {item.release_date ? ( +

+ + event + + {prettyDate(item.release_date)} +

+ ) : ( + "" + )} + {item.price ? ( +

+ + shopping_cart + + {prettyPrice(item.price)} +

+ ) : ( + "" + )} +
+ ) : ( + "" + )}
); } - diff --git a/src/graphql/operation.graphql b/src/graphql/operation.graphql index 98739bb..5866cb8 100644 --- a/src/graphql/operation.graphql +++ b/src/graphql/operation.graphql @@ -124,58 +124,119 @@ query getChronologyItems($language_code: String) { } query getLibraryItemsPreview($language_code: String) { - libraryItems( - filters: { root_item: { eq: true } } - pagination: { limit: -1 } - sort: ["title:asc", "subtitle:asc"] - ) { - data { - id - attributes { - title - subtitle - slug - thumbnail { - data { - attributes { - name - alternativeText - caption - width - height - url - } - } - } - release_date { - year - month - day - } - price { - amount - currency { - data { - attributes { - symbol - code - } - } - } - } - size { - width - height - thickness - } - descriptions(filters: { language: { code: { eq: $language_code } } }) { - description - } - } - } - } + libraryItems( + filters: { root_item: { eq: true } } + pagination: { limit: -1 } + sort: ["title:asc", "subtitle:asc"] + ) { + data { + id + attributes { + title + subtitle + slug + thumbnail { + data { + attributes { + name + alternativeText + caption + width + height + url + } + } + } + release_date { + year + month + day + } + price { + amount + currency { + data { + attributes { + symbol + code + } + } + } + } + metadata { + __typename + ... on ComponentMetadataBooks { + subtype { + data { + attributes { + slug + titles( + filters: { language: { code: { eq: $language_code } } } + ) { + title + } + } + } + } + } + ... on ComponentMetadataGame { + platform { + data { + attributes { + short + } + } + } + } + ... on ComponentMetadataVideo { + subtype { + data { + attributes { + slug + titles( + filters: { language: { code: { eq: $language_code } } } + ) { + title + } + } + } + } + } + ... on ComponentMetadataAudio { + subtype { + data { + attributes { + slug + titles( + filters: { language: { code: { eq: $language_code } } } + ) { + title + } + } + } + } + } + ... on ComponentMetadataOther { + subtype { + data { + attributes { + slug + titles( + filters: { language: { code: { eq: $language_code } } } + ) { + title + } + } + } + } + } + } + } + } + } } + query getLibraryItemsSlugs { libraryItems(pagination: { limit: -1 }) { data { diff --git a/src/graphql/operations-types.ts b/src/graphql/operations-types.ts index 5f9206f..be45c72 100644 --- a/src/graphql/operations-types.ts +++ b/src/graphql/operations-types.ts @@ -263,16 +263,90 @@ export type GetLibraryItemsPreviewQuery = { }; }; }; - size: { - __typename: "ComponentBasicsSize"; - width: number; - height: number; - thickness: number; - }; - descriptions: Array<{ - __typename: "ComponentTranslationsLibraryItems"; - description: string; - }>; + metadata: Array< + | { + __typename: "ComponentMetadataBooks"; + subtype: { + __typename: "TextualSubtypeEntityResponse"; + data: { + __typename: "TextualSubtypeEntity"; + attributes: { + __typename: "TextualSubtype"; + slug: string; + titles: Array<{ + __typename: "ComponentTranslationsSimpleTitle"; + title: string; + }>; + }; + }; + }; + } + | { + __typename: "ComponentMetadataVideo"; + subtype: { + __typename: "VideoSubtypeEntityResponse"; + data: { + __typename: "VideoSubtypeEntity"; + attributes: { + __typename: "VideoSubtype"; + slug: string; + titles: Array<{ + __typename: "ComponentTranslationsSimpleTitle"; + title: string; + }>; + }; + }; + }; + } + | { + __typename: "ComponentMetadataGame"; + platform: { + __typename: "GamePlatformEntityResponse"; + data: { + __typename: "GamePlatformEntity"; + attributes: { + __typename: "GamePlatform"; + short: string; + }; + }; + }; + } + | { + __typename: "ComponentMetadataAudio"; + subtype: { + __typename: "AudioSubtypeEntityResponse"; + data: { + __typename: "AudioSubtypeEntity"; + attributes: { + __typename: "AudioSubtype"; + slug: string; + titles: Array<{ + __typename: "ComponentTranslationsSimpleTitle"; + title: string; + }>; + }; + }; + }; + } + | { + __typename: "ComponentMetadataOther"; + subtype: { + __typename: "OtherSubtypeEntityResponse"; + data: { + __typename: "OtherSubtypeEntity"; + attributes: { + __typename: "OtherSubtype"; + slug: string; + titles: Array<{ + __typename: "ComponentTranslationsSimpleTitle"; + title: string; + }>; + }; + }; + }; + } + | { __typename: "Error" } + >; }; }>; }; diff --git a/src/pages/library/items/[slug].tsx b/src/pages/library/items/[slug].tsx index c398c1d..8b292ff 100644 --- a/src/pages/library/items/[slug].tsx +++ b/src/pages/library/items/[slug].tsx @@ -19,6 +19,8 @@ import { getAssetURL, prettyDate, prettyinlineTitle, + prettyItemType, + prettyItemSubType, prettyPrice, prettySlug, } from "queries/helpers"; @@ -29,7 +31,7 @@ import Chip from "components/Chip"; import Button from "components/Button"; import HorizontalLine from "components/HorizontalLine"; import AppLayout from "components/AppLayout"; -import LibraryMediaPreview from "components/Library/LibraryItemsPreview"; +import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; type LibrarySlugProps = { libraryItem: GetLibraryItemQuery; @@ -194,19 +196,11 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { {item.metadata.length > 0 ? (

{langui.global_type}

- +
+ {prettyItemType(item.metadata[0], langui)} + {"›"} + {prettyItemSubType(item.metadata[0])} +
) : ( "" @@ -273,19 +267,6 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.metadata[0].__typename === "ComponentMetadataBooks" ? ( <> -
-

{langui.global_type}:

- - {item.metadata[0].subtype.data.attributes.titles - .length > 0 - ? item.metadata[0].subtype.data.attributes.titles[0] - .title - : prettySlug( - item.metadata[0].subtype.data.attributes.slug - )} - -
-

{langui.global_pages}:

{item.metadata[0].page_count}

@@ -368,11 +349,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (

{langui.library_item_variants}

-
+
{item.subitems.data.map((variant) => ( - ))}
@@ -380,11 +362,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { ) : (

{langui.library_item_subitems}

-
+
{item.subitems.data.map((subitem) => ( - ))}
diff --git a/src/pages/library/items/index.tsx b/src/pages/library/items/index.tsx index 6850d36..3779369 100644 --- a/src/pages/library/items/index.tsx +++ b/src/pages/library/items/index.tsx @@ -41,9 +41,13 @@ export default function Library(props: LibraryProps): JSX.Element { ); const contentPanel = ( -
+
{props.libraryItems.libraryItems.data.map((item) => ( - + ))}
diff --git a/src/queries/helpers.ts b/src/queries/helpers.ts index 6ffc7ac..4c308bd 100644 --- a/src/queries/helpers.ts +++ b/src/queries/helpers.ts @@ -1,4 +1,7 @@ -import { GetLibraryItemsPreviewQuery } from "graphql/operations-types"; +import { + GetLibraryItemsPreviewQuery, + GetWebsiteInterfaceQuery, +} from "graphql/operations-types"; export function getAssetURL(url: string): string { return process.env.NEXT_PUBLIC_URL_CMS + url; @@ -45,6 +48,47 @@ export function prettyinlineTitle( return result; } +export function prettyItemType( + metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number], + langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"] +): string { + const type = metadata.__typename; + switch (metadata.__typename) { + case "ComponentMetadataAudio": + return langui.library_item_type_audio; + case "ComponentMetadataBooks": + return langui.library_item_type_textual; + case "ComponentMetadataGame": + return langui.library_item_type_game; + case "ComponentMetadataVideo": + return langui.library_item_type_video; + case "ComponentMetadataOther": + return langui.library_item_type_other; + default: + return ""; + } +} + +export function prettyItemSubType( + metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number], +): string { + switch (metadata.__typename) { + case "ComponentMetadataAudio": + case "ComponentMetadataBooks": + case "ComponentMetadataVideo": + case "ComponentMetadataOther": { + return metadata.subtype.data.attributes.titles.length > 0 + ? metadata.subtype.data.attributes.titles[0].title + : prettySlug(metadata.subtype.data.attributes.slug); + } + case "ComponentMetadataGame": + return metadata.platform.data.attributes.short; + + default: + return ""; + } +} + export function capitalizeString(string: string): string { function capitalizeWord(word: string): string { return word.charAt(0).toUpperCase() + word.substring(1); diff --git a/src/tailwind.css b/src/tailwind.css index 95e43c0..f7dd6c9 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -5,7 +5,7 @@ @layer base { html, body { - @apply p-0 m-0 bg-light text-black; + @apply p-0 m-0 bg-light text-black mobile:text-[90%]; } * { @@ -41,7 +41,7 @@ } *::-webkit-scrollbar { - @apply w-3; + @apply w-3 mobile:w-0; } *::-webkit-scrollbar-track { diff --git a/tailwind.config.js b/tailwind.config.js index 06f055d..028ce33 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -14,9 +14,11 @@ module.exports = { headers: ["Vollkorn"], }, screens: { - desktop: {'min': '70rem'}, - mobile: {'max': '70rem'}, - } + desktop: { min: "70rem" }, + mobile: { max: "70rem" }, + coarse: { raw: "(pointer: coarse)" }, + fine: { raw: "(pointer: fine)" }, + }, }, plugins: [ require("@tailwindcss/typography"),