diff --git a/package-lock.json b/package-lock.json index e9fc868..a6f4ebf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "next": "^12.1.0", "react": "17.0.2", "react-dom": "17.0.2", + "react-image-lightbox": "^5.1.4", "react-swipeable": "^6.2.0", "turndown": "^7.1.1" }, @@ -1707,6 +1708,11 @@ "node": ">=0.10.0" } }, + "node_modules/exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2982,7 +2988,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -3055,11 +3060,46 @@ "react": "17.0.2" } }, + "node_modules/react-image-lightbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz", + "integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==", + "dependencies": { + "prop-types": "^15.7.2", + "react-modal": "^3.11.1" + }, + "peerDependencies": { + "react": "16.x || 17.x", + "react-dom": "16.x || 17.x" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-modal": { + "version": "3.14.4", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz", + "integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==", + "dependencies": { + "exenv": "^1.2.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16 || ^17", + "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17" + } }, "node_modules/react-swipeable": { "version": "6.2.0", @@ -3577,6 +3617,14 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4858,6 +4906,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5761,7 +5814,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -5805,11 +5857,35 @@ "scheduler": "^0.20.2" } }, + "react-image-lightbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz", + "integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==", + "requires": { + "prop-types": "^15.7.2", + "react-modal": "^3.11.1" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-modal": { + "version": "3.14.4", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz", + "integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==", + "requires": { + "exenv": "^1.2.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + } }, "react-swipeable": { "version": "6.2.0", @@ -6171,6 +6247,14 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 07b9196..69a7da8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "next": "^12.1.0", "react": "17.0.2", "react-dom": "17.0.2", + "react-image-lightbox": "^5.1.4", "react-swipeable": "^6.2.0", "turndown": "^7.1.1" }, diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 4d43c9d..97fc640 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -111,6 +111,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { return (
> | Dispatch>; state: boolean; - image?: StrapiImage; + images: string[]; + index: number; + setIndex: Dispatch>; }; export default function LightBox(props: LightBoxProps): JSX.Element { + const { state, setState, images, index, setIndex } = props; return ( - - - + <> + {state && ( + document.getElementById("MyAppLayout"), + }} + mainSrc={images[index]} + prevSrc={index > 0 ? images[index - 1] : undefined} + nextSrc={index < images.length ? images[index + 1] : undefined} + onMovePrevRequest={() => setIndex(index - 1)} + onMoveNextRequest={() => setIndex(index + 1)} + imageCaption="" + imageTitle="" + onCloseRequest={() => setState(false)} + imagePadding={50} + /> + )} + ); } diff --git a/src/components/Markdown/Markdawn.tsx b/src/components/Markdown/Markdawn.tsx index 9720884..4cb08c1 100644 --- a/src/components/Markdown/Markdawn.tsx +++ b/src/components/Markdown/Markdawn.tsx @@ -1,11 +1,12 @@ import HorizontalLine from "components/HorizontalLine"; -import Img, { ImageQuality } from "components/Img"; +import Img, { getAssetURL, ImageQuality } from "components/Img"; import InsetBox from "components/InsetBox"; +import LightBox from "components/LightBox"; import ToolTip from "components/ToolTip"; import { useAppLayout } from "contexts/AppLayoutContext"; import Markdown from "markdown-to-jsx"; import { slugify } from "queries/helpers"; -import React from "react"; +import React, { useState } from "react"; type ScenBreakProps = { className?: string; @@ -16,233 +17,262 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element { const appLayout = useAppLayout(); const text = preprocessMarkDawn(props.text); + const [lightboxOpen, setLightboxOpen] = useState(false); + const [lightboxImages, setLightboxImages] = useState([""]); + const [lightboxIndex, setLightboxIndex] = useState(0); + if (text) { return ( - { - return ( -
-

+ <> + + { + return ( +
+

+ {props.children} +

+ +
+ ); + }, + }, + h2: { + component: (props: { + id: string; + style: React.CSSProperties; + children: React.ReactNode; + }) => { + return ( +
+

+ {props.children} +

+ +
+ ); + }, + }, + h3: { + component: (props: { + id: string; + style: React.CSSProperties; + children: React.ReactNode; + }) => { + return ( +
+

+ {props.children} +

+ +
+ ); + }, + }, + h4: { + component: (props: { + id: string; + style: React.CSSProperties; + children: React.ReactNode; + }) => { + return ( +
+

+ {props.children} +

+ +
+ ); + }, + }, + h5: { + component: (props: { + id: string; + style: React.CSSProperties; + children: React.ReactNode; + }) => { + return ( +
+
+ {props.children} +
+ +
+ ); + }, + }, + h6: { + component: (props: { + id: string; + style: React.CSSProperties; + children: React.ReactNode; + }) => { + return ( +
+
+ {props.children} +
+ +
+ ); + }, + }, + Sep: { + component: () => { + return
; + }, + }, + SceneBreak: { + component: (props: { id: string }) => { + return ( +
+ * * * +
+ ); + }, + }, + player: { + component: () => { + return ( + + {appLayout.playerName ? appLayout.playerName : ""} + + ); + }, + }, + Transcript: { + component: (props) => { + return ( +
{props.children} -

- -
- ); +
+ ); + }, }, - }, - h2: { - component: (props: { - id: string; - style: React.CSSProperties; - children: React.ReactNode; - }) => { - return ( -
-

+ Line: { + component: (props) => { + return ( + <> + + {props.name} + +

{props.children}

+ + ); + }, + }, + InsetBox: { + component: (props) => { + return ( + {props.children} + ); + }, + }, + li: { + component: (props: { children: React.ReactNode }) => { + return ( +
  • 100 + ? "my-4" + : "" + } + > {props.children} -
  • - -
    - ); + + ); + }, + }, + Highlight: { + component: (props: { children: React.ReactNode }) => { + return {props.children}; + }, + }, + footer: { + component: (props: { children: React.ReactNode }) => { + return ( + <> + +
    {props.children}
    + + ); + }, + }, + img: { + component: (props: { + alt: string; + src: string; + width?: number; + height?: number; + caption?: string; + name?: string; + }) => { + return ( +
    { + setLightboxOpen(true); + setLightboxImages([ + props.src.startsWith("/uploads/") + ? getAssetURL(props.src, ImageQuality.Large) + : props.src, + ]); + setLightboxIndex(0); + }} + > + {props.src.startsWith("/uploads/") ? ( +
    + +
    + ) : ( +
    + +
    + )} +
    + ); + }, }, }, - h3: { - component: (props: { - id: string; - style: React.CSSProperties; - children: React.ReactNode; - }) => { - return ( -
    -

    - {props.children} -

    - -
    - ); - }, - }, - h4: { - component: (props: { - id: string; - style: React.CSSProperties; - children: React.ReactNode; - }) => { - return ( -
    -

    - {props.children} -

    - -
    - ); - }, - }, - h5: { - component: (props: { - id: string; - style: React.CSSProperties; - children: React.ReactNode; - }) => { - return ( -
    -
    - {props.children} -
    - -
    - ); - }, - }, - h6: { - component: (props: { - id: string; - style: React.CSSProperties; - children: React.ReactNode; - }) => { - return ( -
    -
    - {props.children} -
    - -
    - ); - }, - }, - Sep: { - component: () => { - return
    ; - }, - }, - SceneBreak: { - component: (props: { id: string }) => { - return ( -
    - * * * -
    - ); - }, - }, - player: { - component: () => { - return ( - - {appLayout.playerName ? appLayout.playerName : ""} - - ); - }, - }, - Transcript: { - component: (props) => { - return ( -
    - {props.children} -
    - ); - }, - }, - Line: { - component: (props) => { - return ( - <> - - {props.name} - -

    {props.children}

    - - ); - }, - }, - InsetBox: { - component: (props) => { - return {props.children}; - }, - }, - li: { - component: (props: { children: React.ReactNode }) => { - return ( -
  • 100 - ? "my-4" - : "" - } - > - {props.children} -
  • - ); - }, - }, - Highlight: { - component: (props: { children: React.ReactNode }) => { - return {props.children}; - }, - }, - footer: { - component: (props: { children: React.ReactNode }) => { - return ( - <> - -
    {props.children}
    - - ); - }, - }, - img: { - component: (props: { - alt: string; - src: string; - width?: number; - height?: number; - caption?: string; - name?: string; - }) => { - return ( - <> - {props.src.startsWith("/uploads/") ? ( -
    - -
    - ) : ( -
    - -
    - )} - - ); - }, - }, - }, - }} - > - {text} - + }} + > + {text} + + ); } return <>; @@ -334,3 +364,6 @@ function markdawnHeadersParser( visitedSlugs.push(newSlug); return `<${headerLevels[headerLevel]} id="${newSlug}">${lineText}`; } +function getAssetUrl(): React.SetStateAction { + throw new Error("Function not implemented."); +} diff --git a/src/pages/library/[slug].tsx b/src/pages/library/[slug].tsx index c713bdb..be235bc 100644 --- a/src/pages/library/[slug].tsx +++ b/src/pages/library/[slug].tsx @@ -7,7 +7,6 @@ import { Enum_Componentmetadatabooks_Binding_Type, Enum_Componentmetadatabooks_Page_Order, GetLibraryItemQuery, - StrapiImage, } from "graphql/operations-types"; import { convertMmToInch, @@ -30,13 +29,12 @@ import Button from "components/Button"; import AppLayout from "components/AppLayout"; import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; import InsetBox from "components/InsetBox"; -import Img, { ImageQuality } from "components/Img"; +import Img, { getAssetURL, ImageQuality } from "components/Img"; import { useAppLayout } from "contexts/AppLayoutContext"; import { useRouter } from "next/router"; import ContentTOCLine from "components/Library/ContentTOCLine"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { useState } from "react"; -import Popup from "components/Popup"; import LightBox from "components/LightBox"; interface LibrarySlugProps extends AppStaticProps { @@ -56,8 +54,9 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { sortContent(item.contents); - const [lightboxOpened, setLightboxOpened] = useState(false); - const [lightboxImage, setLightboxImage] = useState(); + const [lightboxOpen, setLightboxOpen] = useState(false); + const [lightboxImages, setLightboxImages] = useState([""]); + const [lightboxIndex, setLightboxIndex] = useState(0); const subPanel = ( @@ -112,9 +111,11 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { const contentPanel = ( { - if (item.thumbnail.data) { - setLightboxImage(item.thumbnail.data.attributes); - setLightboxOpened(true); - } + setLightboxOpen(true); + setLightboxImages([ + getAssetURL( + item.thumbnail.data.attributes.url, + ImageQuality.Large + ), + ]); + setLightboxIndex(0); }} > {item.thumbnail.data ? (

    {langui.gallery}

    - {item.gallery.data.map((galleryItem) => ( + {item.gallery.data.map((galleryItem, index) => (
    { - setLightboxImage(galleryItem.attributes); - setLightboxOpened(true); + setLightboxOpen(true); + setLightboxImages( + item.gallery.data.map((image) => { + return getAssetURL( + image.attributes.url, + ImageQuality.Large + ); + }) + ); + setLightboxIndex(index); }} >
    diff --git a/src/tailwind.css b/src/tailwind.css index e4a8203..14a9584 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -143,6 +143,8 @@ } } +/* TIPPY */ + .tippy-box[data-animation="fade"][data-state="hidden"] { @apply opacity-0; } @@ -205,3 +207,297 @@ .tippy-content { @apply relative px-6 py-4 z-10; } + +/* LIGHTBOX */ + +@keyframes closeWindow { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.ril__outer { + @apply h-full w-full touch-none outline-none bg-shade bg-opacity-50 [backdrop-filter:blur(2px)]; +} + +.ril__outerClosing { + opacity: 0; +} + +.ril__inner { + @apply absolute inset-0; +} + +.ril__image, +.ril__imagePrev, +.ril__imageNext { + @apply absolute inset-0 m-auto max-w-none touch-none; +} + +.ril__image { + @apply drop-shadow-shade-2xl; +} + +.ril__navButtons { + @apply absolute inset-y-0 w-5 h-8 px-10 py-8 cursor-pointer m-auto; +} +.ril__navButtons:hover { + opacity: 1; +} +.ril__navButtons:active { + opacity: 0.7; +} + +.ril__navButtonPrev { + left: 0; + background: rgba(0, 0, 0, 0.2) + url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjM0Ij48cGF0aCBkPSJtIDE5LDMgLTIsLTIgLTE2LDE2IDE2LDE2IDEsLTEgLTE1LC0xNSAxNSwtMTUgeiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==") + no-repeat center; +} + +.ril__navButtonNext { + right: 0; + background: rgba(0, 0, 0, 0.2) + url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjM0Ij48cGF0aCBkPSJtIDEsMyAyLC0yIDE2LDE2IC0xNiwxNiAtMSwtMSAxNSwtMTUgLTE1LC0xNSB6IiBmaWxsPSIjRkZGIi8+PC9zdmc+") + no-repeat center; +} + +.ril__caption, +.ril__toolbar { + @apply bg-shade bg-opacity-50 absolute inset-x-0 flex justify-between; +} + +.ril__caption { + bottom: 0; + max-height: 150px; + overflow: auto; +} + +.ril__captionContent { + padding: 10px 20px; + color: #fff; +} + +.ril__toolbar { + @apply top-0 h-12; +} + +.ril__toolbarSide { + height: 50px; + margin: 0; +} + +.ril__toolbarLeftSide { + padding-left: 20px; + padding-right: 0; + flex: 0 1 auto; + overflow: hidden; + text-overflow: ellipsis; +} + +.ril__toolbarRightSide { + padding-left: 0; + padding-right: 20px; + flex: 0 0 auto; +} + +.ril__toolbarItem { + display: inline-block; + line-height: 50px; + padding: 0; + color: #fff; + font-size: 120%; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ril__toolbarItemChild { + vertical-align: middle; +} + +.ril__builtinButton { + width: 40px; + height: 35px; + cursor: pointer; + border: none; + opacity: 0.7; +} +.ril__builtinButton:hover { + opacity: 1; +} +.ril__builtinButton:active { + outline: none; +} + +.ril__builtinButtonDisabled { + cursor: default; + opacity: 0.5; +} +.ril__builtinButtonDisabled:hover { + opacity: 0.5; +} + +.ril__closeButton { + background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48cGF0aCBkPSJtIDEsMyAxLjI1LC0xLjI1IDcuNSw3LjUgNy41LC03LjUgMS4yNSwxLjI1IC03LjUsNy41IDcuNSw3LjUgLTEuMjUsMS4yNSAtNy41LC03LjUgLTcuNSw3LjUgLTEuMjUsLTEuMjUgNy41LC03LjUgLTcuNSwtNy41IHoiIGZpbGw9IiNGRkYiLz48L3N2Zz4=") + no-repeat center; +} + +.ril__zoomInButton { + background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PGcgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PHBhdGggZD0iTTEgMTlsNi02Ii8+PHBhdGggZD0iTTkgOGg2Ii8+PHBhdGggZD0iTTEyIDV2NiIvPjwvZz48Y2lyY2xlIGN4PSIxMiIgY3k9IjgiIHI9IjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+") + no-repeat center; +} + +.ril__zoomOutButton { + background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PGcgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PHBhdGggZD0iTTEgMTlsNi02Ii8+PHBhdGggZD0iTTkgOGg2Ii8+PC9nPjxjaXJjbGUgY3g9IjEyIiBjeT0iOCIgcj0iNyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiLz48L3N2Zz4=") + no-repeat center; +} + +.ril__outerAnimating { + animation-name: closeWindow; +} + +@keyframes pointFade { + 0%, + 19.999%, + 100% { + opacity: 0; + } + 20% { + opacity: 1; + } +} + +.ril__loadingCircle { + width: 60px; + height: 60px; + position: relative; +} + +.ril__loadingCirclePoint { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; +} +.ril__loadingCirclePoint::before { + content: ""; + display: block; + margin: 0 auto; + width: 11%; + height: 30%; + background-color: #fff; + border-radius: 30%; + animation: pointFade 800ms infinite ease-in-out both; +} +.ril__loadingCirclePoint:nth-of-type(1) { + transform: rotate(0deg); +} +.ril__loadingCirclePoint:nth-of-type(7) { + transform: rotate(180deg); +} +.ril__loadingCirclePoint:nth-of-type(1)::before, +.ril__loadingCirclePoint:nth-of-type(7)::before { + animation-delay: -800ms; +} +.ril__loadingCirclePoint:nth-of-type(2) { + transform: rotate(30deg); +} +.ril__loadingCirclePoint:nth-of-type(8) { + transform: rotate(210deg); +} +.ril__loadingCirclePoint:nth-of-type(2)::before, +.ril__loadingCirclePoint:nth-of-type(8)::before { + animation-delay: -666ms; +} +.ril__loadingCirclePoint:nth-of-type(3) { + transform: rotate(60deg); +} +.ril__loadingCirclePoint:nth-of-type(9) { + transform: rotate(240deg); +} +.ril__loadingCirclePoint:nth-of-type(3)::before, +.ril__loadingCirclePoint:nth-of-type(9)::before { + animation-delay: -533ms; +} +.ril__loadingCirclePoint:nth-of-type(4) { + transform: rotate(90deg); +} +.ril__loadingCirclePoint:nth-of-type(10) { + transform: rotate(270deg); +} +.ril__loadingCirclePoint:nth-of-type(4)::before, +.ril__loadingCirclePoint:nth-of-type(10)::before { + animation-delay: -400ms; +} +.ril__loadingCirclePoint:nth-of-type(5) { + transform: rotate(120deg); +} +.ril__loadingCirclePoint:nth-of-type(11) { + transform: rotate(300deg); +} +.ril__loadingCirclePoint:nth-of-type(5)::before, +.ril__loadingCirclePoint:nth-of-type(11)::before { + animation-delay: -266ms; +} +.ril__loadingCirclePoint:nth-of-type(6) { + transform: rotate(150deg); +} +.ril__loadingCirclePoint:nth-of-type(12) { + transform: rotate(330deg); +} +.ril__loadingCirclePoint:nth-of-type(6)::before, +.ril__loadingCirclePoint:nth-of-type(12)::before { + animation-delay: -133ms; +} +.ril__loadingCirclePoint:nth-of-type(7) { + transform: rotate(180deg); +} +.ril__loadingCirclePoint:nth-of-type(13) { + transform: rotate(360deg); +} +.ril__loadingCirclePoint:nth-of-type(7)::before, +.ril__loadingCirclePoint:nth-of-type(13)::before { + animation-delay: 0ms; +} + +.ril__loadingContainer { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.ril__imagePrev .ril__loadingContainer, +.ril__imageNext .ril__loadingContainer { + display: none; +} + +.ril__errorContainer { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + color: #fff; +} +.ril__imagePrev .ril__errorContainer, +.ril__imageNext .ril__errorContainer { + display: none; +} + +.ril__loadingContainer__icon { + color: #fff; + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); +}