Put an end to my useMemo craze + fixed ios
This commit is contained in:
parent
c356679813
commit
6a1be38613
|
@ -25,7 +25,7 @@
|
||||||
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
||||||
|
|
||||||
- Language: [TypeScript](https://www.typescriptlang.org/)
|
- Language: [TypeScript](https://www.typescriptlang.org/)
|
||||||
- Framework: [Next.js 12](https://nextjs.org/) (React 18)
|
- Framework: [Next.js 13](https://nextjs.org/) (React 18)
|
||||||
- Queries: [GraphQL Code Generator](https://www.graphql-code-generator.com/)
|
- Queries: [GraphQL Code Generator](https://www.graphql-code-generator.com/)
|
||||||
- Fetch the GraphQL schema from the GraphQL back-end endpoint
|
- Fetch the GraphQL schema from the GraphQL back-end endpoint
|
||||||
- Read the operations and fragments stored as graphql files in the `src/graphql` folder
|
- Read the operations and fragments stored as graphql files in the `src/graphql` folder
|
||||||
|
|
|
@ -6,7 +6,6 @@ const locales = ["en", "es", "fr", "pt-br", "ja"];
|
||||||
|
|
||||||
/* @type {import('next').NextConfig} */
|
/* @type {import('next').NextConfig} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
swcMinify: true,
|
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
poweredByHeader: false,
|
poweredByHeader: false,
|
||||||
i18n: {
|
i18n: {
|
||||||
|
|
|
@ -1 +1,91 @@
|
||||||
{"currencies":{"data":[{"id":"1","attributes":{"code":"EUR","symbol":"€","rate_to_usd":1.036166,"display_decimals":true}},{"id":"2","attributes":{"code":"CAD","symbol":"$","rate_to_usd":0.79319156,"display_decimals":true}},{"id":"3","attributes":{"code":"USD","symbol":"$","rate_to_usd":1,"display_decimals":true}},{"id":"4","attributes":{"code":"JPY","symbol":"¥","rate_to_usd":0.0083864261,"display_decimals":false}},{"id":"5","attributes":{"code":"BRL","symbol":"R$","rate_to_usd":0.19904328,"display_decimals":true}},{"id":"6","attributes":{"code":"GBP","symbol":"£","rate_to_usd":1.3181323,"display_decimals":true}},{"id":"7","attributes":{"code":"AUD","symbol":"$","rate_to_usd":0.7422,"display_decimals":true}},{"id":"8","attributes":{"code":"INR","symbol":"₹","rate_to_usd":0.013162881,"display_decimals":false}},{"id":"9","attributes":{"code":"NZD","symbol":"$","rate_to_usd":0.69089984,"display_decimals":true}},{"id":"10","attributes":{"code":"CHF","symbol":"CHF","rate_to_usd":1.0728706,"display_decimals":true}}]}}
|
{
|
||||||
|
"currencies": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"attributes": {
|
||||||
|
"code": "EUR",
|
||||||
|
"symbol": "€",
|
||||||
|
"rate_to_usd": 1.036166,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"attributes": {
|
||||||
|
"code": "CAD",
|
||||||
|
"symbol": "$",
|
||||||
|
"rate_to_usd": 0.79319156,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"attributes": { "code": "USD", "symbol": "$", "rate_to_usd": 1, "display_decimals": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"attributes": {
|
||||||
|
"code": "JPY",
|
||||||
|
"symbol": "¥",
|
||||||
|
"rate_to_usd": 0.0083864261,
|
||||||
|
"display_decimals": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5",
|
||||||
|
"attributes": {
|
||||||
|
"code": "BRL",
|
||||||
|
"symbol": "R$",
|
||||||
|
"rate_to_usd": 0.19904328,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"attributes": {
|
||||||
|
"code": "GBP",
|
||||||
|
"symbol": "£",
|
||||||
|
"rate_to_usd": 1.3181323,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7",
|
||||||
|
"attributes": {
|
||||||
|
"code": "AUD",
|
||||||
|
"symbol": "$",
|
||||||
|
"rate_to_usd": 0.7422,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8",
|
||||||
|
"attributes": {
|
||||||
|
"code": "INR",
|
||||||
|
"symbol": "₹",
|
||||||
|
"rate_to_usd": 0.013162881,
|
||||||
|
"display_decimals": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9",
|
||||||
|
"attributes": {
|
||||||
|
"code": "NZD",
|
||||||
|
"symbol": "$",
|
||||||
|
"rate_to_usd": 0.69089984,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10",
|
||||||
|
"attributes": {
|
||||||
|
"code": "CHF",
|
||||||
|
"symbol": "CHF",
|
||||||
|
"rate_to_usd": 1.0728706,
|
||||||
|
"display_decimals": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1,36 @@
|
||||||
{"languages":{"data":[{"id":"1","attributes":{"name":"French","code":"fr","localized_name":"Français"}},{"id":"2","attributes":{"name":"English","code":"en","localized_name":"English"}},{"id":"3","attributes":{"name":"Japanese","code":"ja","localized_name":"日本語"}},{"id":"4","attributes":{"name":"Spanish","code":"es","localized_name":"Español"}},{"id":"6","attributes":{"name":"Portuguese (Brazil)","code":"pt-br","localized_name":"Português (Brasil)"}},{"id":"8","attributes":{"name":"German","code":"de","localized_name":"Deutsch"}},{"id":"9","attributes":{"name":"Italian","code":"it","localized_name":"Italiano"}},{"id":"10","attributes":{"name":"Russian","code":"ru","localized_name":"русский"}},{"id":"11","attributes":{"name":"Korean","code":"ko","localized_name":"한국어"}},{"id":"12","attributes":{"name":"Chinese (Traditional)","code":"zh-cht","localized_name":"中文(繁體)"}}]}}
|
{
|
||||||
|
"languages": {
|
||||||
|
"data": [
|
||||||
|
{ "id": "1", "attributes": { "name": "French", "code": "fr", "localized_name": "Français" } },
|
||||||
|
{ "id": "2", "attributes": { "name": "English", "code": "en", "localized_name": "English" } },
|
||||||
|
{ "id": "3", "attributes": { "name": "Japanese", "code": "ja", "localized_name": "日本語" } },
|
||||||
|
{ "id": "4", "attributes": { "name": "Spanish", "code": "es", "localized_name": "Español" } },
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"attributes": {
|
||||||
|
"name": "Portuguese (Brazil)",
|
||||||
|
"code": "pt-br",
|
||||||
|
"localized_name": "Português (Brasil)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "id": "8", "attributes": { "name": "German", "code": "de", "localized_name": "Deutsch" } },
|
||||||
|
{
|
||||||
|
"id": "9",
|
||||||
|
"attributes": { "name": "Italian", "code": "it", "localized_name": "Italiano" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10",
|
||||||
|
"attributes": { "name": "Russian", "code": "ru", "localized_name": "русский" }
|
||||||
|
},
|
||||||
|
{ "id": "11", "attributes": { "name": "Korean", "code": "ko", "localized_name": "한국어" } },
|
||||||
|
{
|
||||||
|
"id": "12",
|
||||||
|
"attributes": {
|
||||||
|
"name": "Chinese (Traditional)",
|
||||||
|
"code": "zh-cht",
|
||||||
|
"localized_name": "中文(繁體)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,8 @@
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { useSwipeable } from "react-swipeable";
|
import { useSwipeable } from "react-swipeable";
|
||||||
import { layout } from "../../design.config";
|
import { layout } from "../../design.config";
|
||||||
import { Ico, Icon } from "./Ico";
|
import { Ico, Icon } from "./Ico";
|
||||||
import { MainPanel } from "./Panels/MainPanel";
|
import { MainPanel } from "./Panels/MainPanel";
|
||||||
import { SafariPopup } from "./Panels/SafariPopup";
|
|
||||||
import { isDefined, isUndefined } from "helpers/others";
|
import { isDefined, isUndefined } from "helpers/others";
|
||||||
import { cIf, cJoin } from "helpers/className";
|
import { cIf, cJoin } from "helpers/className";
|
||||||
import { OpenGraph, TITLE_PREFIX, TITLE_SEPARATOR } from "helpers/openGraph";
|
import { OpenGraph, TITLE_PREFIX, TITLE_SEPARATOR } from "helpers/openGraph";
|
||||||
|
@ -77,10 +75,7 @@ export const AppLayout = ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const turnSubIntoContent = useMemo(
|
const turnSubIntoContent = isDefined(subPanel) && isUndefined(contentPanel);
|
||||||
() => isDefined(subPanel) && isUndefined(contentPanel),
|
|
||||||
[contentPanel, subPanel]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -227,7 +222,6 @@ export const AppLayout = ({
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<SafariPopup />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Markdown from "markdown-to-jsx";
|
import Markdown from "markdown-to-jsx";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { Fragment, useMemo } from "react";
|
import React, { Fragment } from "react";
|
||||||
import ReactDOMServer from "react-dom/server";
|
import ReactDOMServer from "react-dom/server";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { Img } from "components/Img";
|
import { Img } from "components/Img";
|
||||||
|
@ -35,11 +35,8 @@ export const Markdawn = ({ className, text: rawText }: MarkdawnProps): JSX.Eleme
|
||||||
const { showLightBox } = useAtomGetter(atoms.lightBox);
|
const { showLightBox } = useAtomGetter(atoms.lightBox);
|
||||||
|
|
||||||
/* eslint-disable no-irregular-whitespace */
|
/* eslint-disable no-irregular-whitespace */
|
||||||
const text = useMemo(
|
const text = `${preprocessMarkDawn(rawText, playerName)}
|
||||||
() => `${preprocessMarkDawn(rawText, playerName)}
|
`;
|
||||||
`,
|
|
||||||
[playerName, rawText]
|
|
||||||
);
|
|
||||||
/* eslint-enable no-irregular-whitespace */
|
/* eslint-enable no-irregular-whitespace */
|
||||||
|
|
||||||
if (isUndefined(text) || text === "") {
|
if (isUndefined(text) || text === "") {
|
||||||
|
@ -219,19 +216,17 @@ export const Markdawn = ({ className, text: rawText }: MarkdawnProps): JSX.Eleme
|
||||||
interface TableOfContentsProps {
|
interface TableOfContentsProps {
|
||||||
text: string;
|
text: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
horizontalLine?: boolean;
|
horizontalLine?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TableOfContents = ({
|
export const TableOfContents = ({
|
||||||
text,
|
text,
|
||||||
title,
|
title,
|
||||||
|
|
||||||
horizontalLine = false,
|
horizontalLine = false,
|
||||||
}: TableOfContentsProps): JSX.Element => {
|
}: TableOfContentsProps): JSX.Element => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const toc = useMemo(() => getTocFromMarkdawn(preprocessMarkDawn(text), title), [text, title]);
|
const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -268,8 +263,7 @@ interface HeaderProps {
|
||||||
|
|
||||||
const Header = ({ level, title, slug }: HeaderProps): JSX.Element => {
|
const Header = ({ level, title, slug }: HeaderProps): JSX.Element => {
|
||||||
const isHoverable = useDeviceSupportsHover();
|
const isHoverable = useDeviceSupportsHover();
|
||||||
const innerComponent = useMemo(
|
const innerComponent = (
|
||||||
() => (
|
|
||||||
<>
|
<>
|
||||||
<div className="ml-10 flex place-items-center gap-4">
|
<div className="ml-10 flex place-items-center gap-4">
|
||||||
{title === "* * *" ? (
|
{title === "* * *" ? (
|
||||||
|
@ -287,8 +281,6 @@ const Header = ({ level, title, slug }: HeaderProps): JSX.Element => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
),
|
|
||||||
[isHoverable, slug, title]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
|
@ -349,8 +341,7 @@ const TocLevel = ({
|
||||||
allowIntersection = true,
|
allowIntersection = true,
|
||||||
}: LevelProps): JSX.Element => {
|
}: LevelProps): JSX.Element => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const ids = tocchildren.map((child) => child.slug);
|
||||||
const ids = useMemo(() => tocchildren.map((child) => child.slug), [tocchildren]);
|
|
||||||
const currentIntersection = useIntersectionList(ids);
|
const currentIntersection = useIntersectionList(ids);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { MouseEventHandler, useCallback, useMemo } from "react";
|
import { MouseEventHandler, useCallback } from "react";
|
||||||
import { Ico, Icon } from "components/Ico";
|
import { Ico, Icon } from "components/Ico";
|
||||||
import { ToolTip } from "components/ToolTip";
|
import { ToolTip } from "components/ToolTip";
|
||||||
import { cIf, cJoin } from "helpers/className";
|
import { cIf, cJoin } from "helpers/className";
|
||||||
|
@ -39,10 +39,7 @@ export const NavOption = ({
|
||||||
onClick,
|
onClick,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isActive = useMemo(
|
const isActive = active || router.asPath.startsWith(url);
|
||||||
() => active || router.asPath.startsWith(url),
|
|
||||||
[active, router.asPath, url]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolTip
|
<ToolTip
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { useMemo } from "react";
|
|
||||||
import UAParser from "ua-parser-js";
|
|
||||||
import { useIsClient, useSessionStorage } from "usehooks-ts";
|
|
||||||
import { Button } from "components/Inputs/Button";
|
|
||||||
import { Popup } from "components/Containers/Popup";
|
|
||||||
import { sendAnalytics } from "helpers/analytics";
|
|
||||||
|
|
||||||
export const SafariPopup = (): JSX.Element => {
|
|
||||||
const [hasDisgardedSafariWarning, setHasDisgardedSafariWarning] = useSessionStorage(
|
|
||||||
"hasDisgardedSafariWarning",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
const isClient = useIsClient();
|
|
||||||
const isSafari = useMemo<boolean>(() => {
|
|
||||||
if (isClient) {
|
|
||||||
const parser = new UAParser();
|
|
||||||
return parser.getBrowser().name === "Safari" || parser.getOS().name === "iOS";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}, [isClient]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popup isVisible={isSafari && !hasDisgardedSafariWarning}>
|
|
||||||
<h1 className="text-2xl">Hi, you are using Safari!</h1>
|
|
||||||
<p className="max-w-lg text-center">
|
|
||||||
In most cases this wouldn’t be a problem but our website is—for some obscure
|
|
||||||
reason—performing terribly on Safari (WebKit). Because of that, we have decided to display
|
|
||||||
this message instead of letting you have a slow and painful experience. We are looking into
|
|
||||||
the problem, and are hoping to fix this soon.
|
|
||||||
</p>
|
|
||||||
<p>In the meanwhile, if you are using an iPhone/iPad, please try using another device.</p>
|
|
||||||
<p>If you are on macOS, please use another browser such as Firefox or Chrome.</p>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
text="Let me in regardless"
|
|
||||||
className="mt-8"
|
|
||||||
onClick={() => {
|
|
||||||
setHasDisgardedSafariWarning(true);
|
|
||||||
sendAnalytics("Safari", "Disgard warning");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Popup>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
||||||
|
@ -34,12 +34,8 @@ export const SettingsPopup = (): JSX.Element => {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const currencyOptions = useMemo(
|
const currencyOptions = filterHasAttributes(currencies, ["attributes"] as const).map(
|
||||||
() =>
|
|
||||||
filterHasAttributes(currencies, ["attributes"] as const).map(
|
|
||||||
(currentCurrency) => currentCurrency.attributes.code
|
(currentCurrency) => currentCurrency.attributes.code
|
||||||
),
|
|
||||||
[currencies]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const [currencySelect, setCurrencySelect] = useState<number>(-1);
|
const [currencySelect, setCurrencySelect] = useState<number>(-1);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback } from "react";
|
||||||
import { AppLayout, AppLayoutRequired } from "./AppLayout";
|
import { AppLayout, AppLayoutRequired } from "./AppLayout";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
import { HorizontalLine } from "./HorizontalLine";
|
import { HorizontalLine } from "./HorizontalLine";
|
||||||
|
@ -59,19 +59,13 @@ export const PostPage = ({
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { thumbnail, body, title, excerpt } = useMemo(
|
const thumbnail =
|
||||||
() => ({
|
selectedTranslation?.thumbnail?.data?.attributes ?? post.thumbnail?.data?.attributes;
|
||||||
thumbnail:
|
const body = selectedTranslation?.body ?? "";
|
||||||
selectedTranslation?.thumbnail?.data?.attributes ?? post.thumbnail?.data?.attributes,
|
const title = selectedTranslation?.title ?? prettySlug(post.slug);
|
||||||
body: selectedTranslation?.body ?? "",
|
const excerpt = selectedTranslation?.excerpt ?? "";
|
||||||
title: selectedTranslation?.title ?? prettySlug(post.slug),
|
|
||||||
excerpt: selectedTranslation?.excerpt ?? "",
|
|
||||||
}),
|
|
||||||
[post.slug, post.thumbnail, selectedTranslation]
|
|
||||||
);
|
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel =
|
||||||
() =>
|
|
||||||
returnHref || returnTitle || displayCredits || displayToc ? (
|
returnHref || returnTitle || displayCredits || displayToc ? (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
{returnHref && returnTitle && (
|
{returnHref && returnTitle && (
|
||||||
|
@ -113,22 +107,9 @@ export const PostPage = ({
|
||||||
|
|
||||||
{displayToc && <TableOfContents text={body} title={title} horizontalLine />}
|
{displayToc && <TableOfContents text={body} title={title} horizontalLine />}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
) : undefined,
|
) : undefined;
|
||||||
[
|
|
||||||
body,
|
|
||||||
displayCredits,
|
|
||||||
displayToc,
|
|
||||||
langui,
|
|
||||||
post.authors,
|
|
||||||
returnHref,
|
|
||||||
returnTitle,
|
|
||||||
selectedTranslation,
|
|
||||||
title,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
{returnHref && returnTitle && (
|
{returnHref && returnTitle && (
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
|
@ -176,23 +157,6 @@ export const PostPage = ({
|
||||||
|
|
||||||
{appendBody}
|
{appendBody}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
LanguageSwitcher,
|
|
||||||
appendBody,
|
|
||||||
body,
|
|
||||||
displayLanguageSwitcher,
|
|
||||||
displayThumbnailHeader,
|
|
||||||
displayTitle,
|
|
||||||
excerpt,
|
|
||||||
languageSwitcherProps,
|
|
||||||
post.categories,
|
|
||||||
prependBody,
|
|
||||||
returnHref,
|
|
||||||
returnTitle,
|
|
||||||
thumbnail,
|
|
||||||
title,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout {...otherProps} contentPanel={contentPanel} subPanel={subPanel} />;
|
return <AppLayout {...otherProps} contentPanel={contentPanel} subPanel={subPanel} />;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
import { Ico, Icon } from "./Ico";
|
import { Ico, Icon } from "./Ico";
|
||||||
|
@ -75,8 +75,7 @@ export const PreviewCard = ({
|
||||||
const isHoverable = useDeviceSupportsHover();
|
const isHoverable = useDeviceSupportsHover();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const metadataJSX = useMemo(
|
const metadataJSX = (
|
||||||
() => (
|
|
||||||
<>
|
<>
|
||||||
{metadata && (metadata.releaseDate || metadata.price) && (
|
{metadata && (metadata.releaseDate || metadata.price) && (
|
||||||
<div className="flex w-full flex-row flex-wrap gap-x-3">
|
<div className="flex w-full flex-row flex-wrap gap-x-3">
|
||||||
|
@ -107,8 +106,6 @@ export const PreviewCard = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
),
|
|
||||||
[currencies, currency, metadata, router.locale]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
|
import { Fragment, useCallback, useEffect, useState } from "react";
|
||||||
import { useHotkeys } from "react-hotkeys-hook";
|
import { useHotkeys } from "react-hotkeys-hook";
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
|
@ -87,17 +87,11 @@ export const SmartList = <T,>({
|
||||||
return items;
|
return items;
|
||||||
}, [items, searchingBy, searchingCaseInsensitive, searchingTerm]);
|
}, [items, searchingBy, searchingCaseInsensitive, searchingTerm]);
|
||||||
|
|
||||||
const filteredItems = useMemo(() => {
|
const filteredItems = searchFilter().filter(filteringFunction);
|
||||||
const filteredBySearch = searchFilter();
|
|
||||||
return filteredBySearch.filter(filteringFunction);
|
|
||||||
}, [filteringFunction, searchFilter]);
|
|
||||||
|
|
||||||
const sortedItem = useMemo(
|
const sortedItem = filteredItems.sort(sortingFunction);
|
||||||
() => filteredItems.sort(sortingFunction),
|
|
||||||
[filteredItems, sortingFunction]
|
|
||||||
);
|
|
||||||
|
|
||||||
const groups = useMemo(() => {
|
const groups = (() => {
|
||||||
const memo: Group<T>[] = [];
|
const memo: Group<T>[] = [];
|
||||||
|
|
||||||
sortedItem.forEach((item) => {
|
sortedItem.forEach((item) => {
|
||||||
|
@ -116,9 +110,9 @@ export const SmartList = <T,>({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return memo.sort(groupSortingFunction);
|
return memo.sort(groupSortingFunction);
|
||||||
}, [groupCountingFunction, groupSortingFunction, groupingFunction, sortedItem]);
|
})();
|
||||||
|
|
||||||
const pages = useMemo(() => {
|
const pages = (() => {
|
||||||
const memo: Group<T>[][] = [];
|
const memo: Group<T>[][] = [];
|
||||||
let currentPage: Group<T>[] = [];
|
let currentPage: Group<T>[] = [];
|
||||||
let remainingSlots = paginationItemPerPage;
|
let remainingSlots = paginationItemPerPage;
|
||||||
|
@ -162,7 +156,7 @@ export const SmartList = <T,>({
|
||||||
}
|
}
|
||||||
|
|
||||||
return memo;
|
return memo;
|
||||||
}, [groups, paginationItemPerPage]);
|
})();
|
||||||
|
|
||||||
useHotkeys("left", () => setPage((current) => current - 1), { enabled: page > 0 });
|
useHotkeys("left", () => setPage((current) => current - 1), { enabled: page > 0 });
|
||||||
useHotkeys("right", () => setPage((current) => current + 1), {
|
useHotkeys("right", () => setPage((current) => current + 1), {
|
||||||
|
|
|
@ -84,6 +84,7 @@ export const useSettings = (): void => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (preferredLanguages.length === 0) {
|
if (preferredLanguages.length === 0) {
|
||||||
if (isDefinedAndNotEmpty(router.locale) && router.locales) {
|
if (isDefinedAndNotEmpty(router.locale) && router.locales) {
|
||||||
|
console.log(router.locale, getDefaultPreferredLanguages(router.locale, router.locales));
|
||||||
setPreferredLanguages(getDefaultPreferredLanguages(router.locale, router.locales));
|
setPreferredLanguages(getDefaultPreferredLanguages(router.locale, router.locales));
|
||||||
}
|
}
|
||||||
} else if (router.locale !== preferredLanguages[0]) {
|
} else if (router.locale !== preferredLanguages[0]) {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { useLayoutEffect } from "react";
|
||||||
|
import { isDefined } from "helpers/others";
|
||||||
|
import { useIsWebkit } from "hooks/useIsWebkit";
|
||||||
|
|
||||||
|
export const useWebkitFixes = (): void => {
|
||||||
|
const isWebkit = useIsWebkit();
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
const next = document.getElementById("__next");
|
||||||
|
if (isDefined(next)) {
|
||||||
|
if (isWebkit) {
|
||||||
|
next.classList.add("webkit-fixes");
|
||||||
|
} else {
|
||||||
|
next.classList.remove("webkit-fixes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWebkit]);
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useIsClient } from "usehooks-ts";
|
import { useIsClient } from "usehooks-ts";
|
||||||
import { isDefined } from "helpers/others";
|
import { isDefined } from "helpers/others";
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export const useFullscreen = (
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
const isClient = useIsClient();
|
const isClient = useIsClient();
|
||||||
|
|
||||||
const elem = useMemo(() => (isClient ? document.querySelector(`#${id}`) : null), [id, isClient]);
|
const elem = isClient ? document.querySelector(`#${id}`) : null;
|
||||||
|
|
||||||
const requestFullscreen = useCallback(() => elem?.requestFullscreen(), [elem]);
|
const requestFullscreen = useCallback(() => elem?.requestFullscreen(), [elem]);
|
||||||
const exitFullscreen = useCallback(
|
const exitFullscreen = useCallback(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { throttle } from "throttle-debounce";
|
import { throttle } from "throttle-debounce";
|
||||||
import { useIsClient } from "usehooks-ts";
|
import { useIsClient } from "usehooks-ts";
|
||||||
import { useOnScroll } from "./useOnScroll";
|
import { useOnScroll } from "./useOnScroll";
|
||||||
|
@ -10,10 +10,7 @@ export const useIntersectionList = (ids: string[]): number => {
|
||||||
|
|
||||||
const isClient = useIsClient();
|
const isClient = useIsClient();
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = isClient ? document.getElementById(Ids.ContentPanel) : null;
|
||||||
() => (isClient ? document.getElementById(Ids.ContentPanel) : null),
|
|
||||||
[isClient]
|
|
||||||
);
|
|
||||||
|
|
||||||
const refreshCurrentIntersection = useCallback(
|
const refreshCurrentIntersection = useCallback(
|
||||||
(scroll: number) => {
|
(scroll: number) => {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import UAParser from "ua-parser-js";
|
||||||
|
import { useIsClient } from "usehooks-ts";
|
||||||
|
|
||||||
|
export const useIsWebkit = (): boolean => {
|
||||||
|
const isClient = useIsClient();
|
||||||
|
return useMemo<boolean>(() => {
|
||||||
|
if (isClient) {
|
||||||
|
const parser = new UAParser();
|
||||||
|
return parser.getBrowser().name === "Safari" || parser.getOS().name === "iOS";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, [isClient]);
|
||||||
|
};
|
|
@ -1,10 +1,10 @@
|
||||||
import { useMemo, useCallback, useEffect } from "react";
|
import { useCallback, useEffect } from "react";
|
||||||
import { useIsClient } from "usehooks-ts";
|
import { useIsClient } from "usehooks-ts";
|
||||||
import { Ids } from "types/ids";
|
import { Ids } from "types/ids";
|
||||||
|
|
||||||
export const useOnScroll = (id: Ids, onScroll: (scroll: number) => void): void => {
|
export const useOnScroll = (id: Ids, onScroll: (scroll: number) => void): void => {
|
||||||
const isClient = useIsClient();
|
const isClient = useIsClient();
|
||||||
const elem = useMemo(() => (isClient ? document.querySelector(`#${id}`) : null), [id, isClient]);
|
const elem = isClient ? document.querySelector(`#${id}`) : null;
|
||||||
const listener = useCallback(() => {
|
const listener = useCallback(() => {
|
||||||
if (elem?.scrollTop) {
|
if (elem?.scrollTop) {
|
||||||
onScroll(elem.scrollTop);
|
onScroll(elem.scrollTop);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Dispatch, SetStateAction, useCallback, useMemo } from "react";
|
import { Dispatch, SetStateAction, useCallback } from "react";
|
||||||
import { useLocalStorage } from "usehooks-ts";
|
import { useLocalStorage } from "usehooks-ts";
|
||||||
import { ImageQuality } from "helpers/img";
|
import { ImageQuality } from "helpers/img";
|
||||||
|
|
||||||
|
@ -94,13 +94,8 @@ export const useReaderSettings = (): {
|
||||||
setTeint,
|
setTeint,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const filterSettings = useMemo(
|
|
||||||
() => ({ bookFold, lighting, paperTexture, teint, dropShadow }),
|
|
||||||
[bookFold, dropShadow, lighting, paperTexture, teint]
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filterSettings,
|
filterSettings: { bookFold, lighting, paperTexture, teint, dropShadow },
|
||||||
isSidePagesEnabled,
|
isSidePagesEnabled,
|
||||||
pageQuality,
|
pageQuality,
|
||||||
toggleBookFold,
|
toggleBookFold,
|
||||||
|
|
|
@ -3,17 +3,20 @@ import { useEffect, useState } from "react";
|
||||||
import { useCounter } from "usehooks-ts";
|
import { useCounter } from "usehooks-ts";
|
||||||
import { isDefined } from "helpers/others";
|
import { isDefined } from "helpers/others";
|
||||||
|
|
||||||
|
const NUM_RETRIES = 10;
|
||||||
|
|
||||||
export const useScrollIntoView = (): void => {
|
export const useScrollIntoView = (): void => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { count, increment } = useCounter(0);
|
const { count, increment } = useCounter(0);
|
||||||
const [hasReachedElem, setHasReachedElem] = useState(false);
|
const [hasReachedElem, setHasReachedElem] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (count < NUM_RETRIES)
|
||||||
if (!hasReachedElem) {
|
if (!hasReachedElem) {
|
||||||
const indexHash = router.asPath.indexOf("#");
|
const indexHash = router.asPath.indexOf("#");
|
||||||
if (indexHash > 0) {
|
if (indexHash > 0) {
|
||||||
const hash = router.asPath.slice(indexHash + 1);
|
const hash = router.asPath.slice(indexHash + 1);
|
||||||
|
if (hash !== "") {
|
||||||
const element = document.getElementById(hash);
|
const element = document.getElementById(hash);
|
||||||
console.log(element);
|
|
||||||
if (isDefined(element)) {
|
if (isDefined(element)) {
|
||||||
console.log(`[useScrollIntoView] ${hash} found`);
|
console.log(`[useScrollIntoView] ${hash} found`);
|
||||||
element.scrollIntoView();
|
element.scrollIntoView();
|
||||||
|
@ -22,11 +25,12 @@ export const useScrollIntoView = (): void => {
|
||||||
console.log(`[useScrollIntoView] ${hash} not found`);
|
console.log(`[useScrollIntoView] ${hash} not found`);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
increment();
|
increment();
|
||||||
}, 100);
|
}, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [increment, router.asPath, count, hasReachedElem, setHasReachedElem]);
|
}
|
||||||
|
}, [router.asPath, hasReachedElem, setHasReachedElem, increment, count]);
|
||||||
|
|
||||||
useEffect(() => setHasReachedElem(false), [router.asPath]);
|
useEffect(() => setHasReachedElem(false), [router.asPath]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,7 @@ export const useSmartLanguage = <T>({
|
||||||
setSelectedTranslationIndex(getPreferredLanguage(preferredLanguages, availableLocales));
|
setSelectedTranslationIndex(getPreferredLanguage(preferredLanguages, availableLocales));
|
||||||
}, [preferredLanguages, availableLocales, router.locale]);
|
}, [preferredLanguages, availableLocales, router.locale]);
|
||||||
|
|
||||||
const selectedTranslation = useMemo(() => {
|
const selectedTranslation = (() => {
|
||||||
if (isDefined(selectedTranslationIndex)) {
|
if (isDefined(selectedTranslationIndex)) {
|
||||||
const item = items[selectedTranslationIndex];
|
const item = items[selectedTranslationIndex];
|
||||||
if (isDefined(item)) {
|
if (isDefined(item)) {
|
||||||
|
@ -44,7 +44,7 @@ export const useSmartLanguage = <T>({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [items, selectedTranslationIndex, transform]);
|
})();
|
||||||
|
|
||||||
const languageSwitcherProps = {
|
const languageSwitcherProps = {
|
||||||
languages: languages,
|
languages: languages,
|
||||||
|
|
|
@ -22,12 +22,14 @@ import { LightBoxProvider } from "contexts/LightBoxProvider";
|
||||||
import { SettingsPopup } from "components/Panels/SettingsPopup";
|
import { SettingsPopup } from "components/Panels/SettingsPopup";
|
||||||
import { useSettings } from "contexts/settings";
|
import { useSettings } from "contexts/settings";
|
||||||
import { useContainerQueries } from "contexts/containerQueries";
|
import { useContainerQueries } from "contexts/containerQueries";
|
||||||
|
import { useWebkitFixes } from "contexts/webkitFixes";
|
||||||
|
|
||||||
const AccordsLibraryApp = (props: AppProps): JSX.Element => {
|
const AccordsLibraryApp = (props: AppProps): JSX.Element => {
|
||||||
useLocalData();
|
useLocalData();
|
||||||
useAppLayout();
|
useAppLayout();
|
||||||
useSettings();
|
useSettings();
|
||||||
useContainerQueries();
|
useContainerQueries();
|
||||||
|
useWebkitFixes();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
|
@ -20,8 +19,7 @@ interface Props extends AppLayoutRequired {}
|
||||||
|
|
||||||
const Archives = (props: Props): JSX.Element => {
|
const Archives = (props: Props): JSX.Element => {
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.Inventory}
|
icon={Icon.Inventory}
|
||||||
|
@ -31,9 +29,8 @@ const Archives = (props: Props): JSX.Element => {
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
<NavOption title={"Videos"} url="/archives/videos/" border />
|
<NavOption title={"Videos"} url="/archives/videos/" border />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout subPanel={subPanel} {...props} />;
|
return <AppLayout subPanel={subPanel} {...props} />;
|
||||||
};
|
};
|
||||||
export default Archives;
|
export default Archives;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useMemo, useState } from "react";
|
import { useState } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
|
@ -51,8 +51,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName);
|
const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/archives/videos/"
|
href="/archives/videos/"
|
||||||
|
@ -82,12 +81,9 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
</WithLabel>
|
</WithLabel>
|
||||||
)}
|
)}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[hoverable, keepInfoVisible, langui, searchName, toggleKeepInfoVisible]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(channel?.videos?.data, ["id", "attributes"] as const)}
|
items={filterHasAttributes(channel?.videos?.data, ["id", "attributes"] as const)}
|
||||||
|
@ -123,8 +119,6 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
searchingBy={(item) => item.attributes.title}
|
searchingBy={(item) => item.attributes.title}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[channel?.title, channel?.videos?.data, isContentPanelAtLeast4xl, keepInfoVisible, searchName]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo, useState } from "react";
|
import { useState } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
|
@ -52,8 +52,7 @@ const Videos = ({ videos, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName);
|
const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/archives/"
|
href="/archives/"
|
||||||
|
@ -79,12 +78,9 @@ const Videos = ({ videos, ...otherProps }: Props): JSX.Element => {
|
||||||
</WithLabel>
|
</WithLabel>
|
||||||
)}
|
)}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[hoverable, keepInfoVisible, langui, searchName, toggleKeepInfoVisible]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(videos, ["id", "attributes"] as const)}
|
items={filterHasAttributes(videos, ["id", "attributes"] as const)}
|
||||||
|
@ -119,8 +115,6 @@ const Videos = ({ videos, ...otherProps }: Props): JSX.Element => {
|
||||||
searchingBy={(item) => item.attributes.title}
|
searchingBy={(item) => item.attributes.title}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[isContentPanelAtLeast4xl, keepInfoVisible, searchName, videos]
|
|
||||||
);
|
);
|
||||||
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
|
@ -34,8 +33,7 @@ const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/archives/videos/"
|
href="/archives/videos/"
|
||||||
|
@ -49,12 +47,9 @@ const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
||||||
<NavOption title={langui.channel} url="#channel" border />
|
<NavOption title={langui.channel} url="#channel" border />
|
||||||
<NavOption title={langui.description} url="#description" border />
|
<NavOption title={langui.description} url="#description" border />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/library/"
|
href="/library/"
|
||||||
|
@ -133,21 +128,6 @@ const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
||||||
</InsetBox>
|
</InsetBox>
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
isContentPanelAtLeast4xl,
|
|
||||||
langui,
|
|
||||||
router.locale,
|
|
||||||
video.channel?.data?.attributes,
|
|
||||||
video.description,
|
|
||||||
video.gone,
|
|
||||||
video.likes,
|
|
||||||
video.published_date,
|
|
||||||
video.source,
|
|
||||||
video.title,
|
|
||||||
video.uid,
|
|
||||||
video.views,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
|
|
@ -67,8 +67,7 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
displayOnlyOn={"1ColumnLayout"}
|
displayOnlyOn={"1ColumnLayout"}
|
||||||
|
@ -85,9 +84,7 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||||
<LanguageSwitcher {...languageSwitcherProps} />
|
<LanguageSwitcher {...languageSwitcherProps} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isDefined(selectedTranslation.body) && (
|
{isDefined(selectedTranslation.body) && <Markdawn text={selectedTranslation.body.body} />}
|
||||||
<Markdawn text={selectedTranslation.body.body} />
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
@ -119,35 +116,16 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
selectedTranslation,
|
|
||||||
languageSwitcherProps,
|
|
||||||
LanguageSwitcher,
|
|
||||||
selectedContentTranslation,
|
|
||||||
ContentLanguageSwitcherProps,
|
|
||||||
ContentLanguageSwitcher,
|
|
||||||
primaryContent?.categories,
|
|
||||||
primaryContent?.type,
|
|
||||||
primaryContent?.thumbnail?.data?.attributes,
|
|
||||||
langui,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
<ReturnButton displayOnlyOn={"3ColumnsLayout"} href="/chronicles" title={langui.chronicles} />
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
|
||||||
href="/chronicles"
|
|
||||||
title={langui.chronicles}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
<div className="grid gap-16">
|
<div className="grid gap-16">
|
||||||
{filterHasAttributes(chapters, ["attributes.chronicles", "id"] as const).map(
|
{filterHasAttributes(chapters, ["attributes.chronicles", "id"] as const).map((chapter) => (
|
||||||
(chapter) => (
|
|
||||||
<TranslatedChroniclesList
|
<TranslatedChroniclesList
|
||||||
key={chapter.id}
|
key={chapter.id}
|
||||||
chronicles={chapter.attributes.chronicles.data}
|
chronicles={chapter.attributes.chronicles.data}
|
||||||
|
@ -160,12 +138,9 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||||
fallback={{ title: prettySlug(chapter.attributes.slug) }}
|
fallback={{ title: prettySlug(chapter.attributes.slug) }}
|
||||||
currentSlug={chronicle.slug}
|
currentSlug={chronicle.slug}
|
||||||
/>
|
/>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[chapters, chronicle.slug, langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Containers/SubPanel";
|
import { SubPanel } from "components/Containers/SubPanel";
|
||||||
|
@ -26,8 +25,7 @@ interface Props extends AppLayoutRequired {
|
||||||
|
|
||||||
const Chronicles = ({ chapters, ...otherProps }: Props): JSX.Element => {
|
const Chronicles = ({ chapters, ...otherProps }: Props): JSX.Element => {
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.WatchLater}
|
icon={Icon.WatchLater}
|
||||||
|
@ -38,8 +36,7 @@ const Chronicles = ({ chapters, ...otherProps }: Props): JSX.Element => {
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
<div className="grid gap-16">
|
<div className="grid gap-16">
|
||||||
{filterHasAttributes(chapters, ["attributes.chronicles", "id"] as const).map(
|
{filterHasAttributes(chapters, ["attributes.chronicles", "id"] as const).map((chapter) => (
|
||||||
(chapter) => (
|
|
||||||
<TranslatedChroniclesList
|
<TranslatedChroniclesList
|
||||||
key={chapter.id}
|
key={chapter.id}
|
||||||
chronicles={chapter.attributes.chronicles.data}
|
chronicles={chapter.attributes.chronicles.data}
|
||||||
|
@ -51,12 +48,9 @@ const Chronicles = ({ chapters, ...otherProps }: Props): JSX.Element => {
|
||||||
}))}
|
}))}
|
||||||
fallback={{ title: prettySlug(chapter.attributes.slug) }}
|
fallback={{ title: prettySlug(chapter.attributes.slug) }}
|
||||||
/>
|
/>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[chapters, langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout subPanel={subPanel} {...otherProps} />;
|
return <AppLayout subPanel={subPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback } from "react";
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
|
@ -62,22 +62,16 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
useScrollTopOnChange(Ids.ContentPanel, [selectedTranslation]);
|
useScrollTopOnChange(Ids.ContentPanel, [selectedTranslation]);
|
||||||
|
|
||||||
const { previousContent, nextContent } = useMemo(
|
const previousContent =
|
||||||
() => ({
|
|
||||||
previousContent:
|
|
||||||
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
|
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
|
||||||
? getPreviousContent(content.folder.data.attributes.contents.data, content.slug)
|
? getPreviousContent(content.folder.data.attributes.contents.data, content.slug)
|
||||||
: undefined,
|
: undefined;
|
||||||
nextContent:
|
const nextContent =
|
||||||
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
|
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
|
||||||
? getNextContent(content.folder.data.attributes.contents.data, content.slug)
|
? getNextContent(content.folder.data.attributes.contents.data, content.slug)
|
||||||
: undefined,
|
: undefined;
|
||||||
}),
|
|
||||||
[content.folder, content.slug]
|
|
||||||
);
|
|
||||||
|
|
||||||
const returnButtonProps = useMemo(
|
const returnButtonProps = {
|
||||||
() => ({
|
|
||||||
href: content.folder?.data?.attributes
|
href: content.folder?.data?.attributes
|
||||||
? `/contents/folder/${content.folder.data.attributes.slug}`
|
? `/contents/folder/${content.folder.data.attributes.slug}`
|
||||||
: "/contents",
|
: "/contents",
|
||||||
|
@ -94,12 +88,9 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
: langui.contents,
|
: langui.contents,
|
||||||
},
|
},
|
||||||
langui,
|
langui,
|
||||||
}),
|
};
|
||||||
[content.folder?.data?.attributes, langui]
|
|
||||||
);
|
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<TranslatedReturnButton {...returnButtonProps} displayOnlyOn="3ColumnsLayout" />
|
<TranslatedReturnButton {...returnButtonProps} displayOnlyOn="3ColumnsLayout" />
|
||||||
|
|
||||||
|
@ -226,9 +217,7 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
] as const).map((rangedContent) => {
|
] as const).map((rangedContent) => {
|
||||||
const libraryItem = rangedContent.attributes.library_item.data;
|
const libraryItem = rangedContent.attributes.library_item.data;
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={libraryItem.attributes.slug} className={cIf(is1ColumnLayout, "w-3/4")}>
|
||||||
key={libraryItem.attributes.slug}
|
|
||||||
className={cIf(is1ColumnLayout, "w-3/4")}>
|
|
||||||
<PreviewCard
|
<PreviewCard
|
||||||
href={`/library/${libraryItem.attributes.slug}`}
|
href={`/library/${libraryItem.attributes.slug}`}
|
||||||
title={libraryItem.attributes.title}
|
title={libraryItem.attributes.title}
|
||||||
|
@ -265,19 +254,9 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
content.ranged_contents?.data,
|
|
||||||
languages,
|
|
||||||
langui,
|
|
||||||
returnButtonProps,
|
|
||||||
selectedTranslation,
|
|
||||||
is1ColumnLayout,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<TranslatedReturnButton
|
<TranslatedReturnButton
|
||||||
{...returnButtonProps}
|
{...returnButtonProps}
|
||||||
|
@ -382,24 +361,6 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
LanguageSwitcher,
|
|
||||||
content.categories,
|
|
||||||
content.thumbnail?.data?.attributes,
|
|
||||||
content.type,
|
|
||||||
isContentPanelAtLeast2xl,
|
|
||||||
languageSwitcherProps,
|
|
||||||
langui,
|
|
||||||
nextContent?.attributes,
|
|
||||||
previousContent?.attributes,
|
|
||||||
returnButtonProps,
|
|
||||||
selectedTranslation?.description,
|
|
||||||
selectedTranslation?.pre_title,
|
|
||||||
selectedTranslation?.subtitle,
|
|
||||||
selectedTranslation?.text_set?.text,
|
|
||||||
selectedTranslation?.title,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useState, useMemo, useCallback } from "react";
|
import { useState, useCallback } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
|
@ -116,8 +116,7 @@ const Contents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
[searchName]
|
[searchName]
|
||||||
);
|
);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.Workspaces}
|
icon={Icon.Workspaces}
|
||||||
|
@ -185,28 +184,9 @@ const Contents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
groupingMethod,
|
|
||||||
hoverable,
|
|
||||||
keepInfoVisible,
|
|
||||||
langui.always_show_info,
|
|
||||||
langui.category,
|
|
||||||
langui.contents,
|
|
||||||
langui.contents_description,
|
|
||||||
langui.group_by,
|
|
||||||
langui.reset_all_filters,
|
|
||||||
langui.search_title,
|
|
||||||
langui.switch_to_folder_view,
|
|
||||||
langui.type,
|
|
||||||
searchName,
|
|
||||||
setKeepInfoVisible,
|
|
||||||
toggleKeepInfoVisible,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(contents, ["attributes", "id"] as const)}
|
items={filterHasAttributes(contents, ["attributes", "id"] as const)}
|
||||||
|
@ -264,15 +244,6 @@ const Contents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
paginationItemPerPage={50}
|
paginationItemPerPage={50}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
isContentPanelAtLeast4xl,
|
|
||||||
contents,
|
|
||||||
filteringFunction,
|
|
||||||
groupingFunction,
|
|
||||||
keepInfoVisible,
|
|
||||||
searchName,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
||||||
|
@ -37,8 +36,7 @@ const ContentsFolder = ({ openGraph, folder, ...otherProps }: Props): JSX.Elemen
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.Workspaces}
|
icon={Icon.Workspaces}
|
||||||
|
@ -50,12 +48,9 @@ const ContentsFolder = ({ openGraph, folder, ...otherProps }: Props): JSX.Elemen
|
||||||
|
|
||||||
<Button href="/contents/all" text={langui.switch_to_grid_view} icon={Icon.Apps} />
|
<Button href="/contents/all" text={langui.switch_to_grid_view} icon={Icon.Apps} />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[langui.contents, langui.contents_description, langui.switch_to_grid_view]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<div className="mb-10 grid grid-flow-col place-items-center justify-start gap-x-2">
|
<div className="mb-10 grid grid-flow-col place-items-center justify-start gap-x-2">
|
||||||
{folder.parent_folder?.data?.attributes && (
|
{folder.parent_folder?.data?.attributes && (
|
||||||
|
@ -171,16 +166,6 @@ const ContentsFolder = ({ openGraph, folder, ...otherProps }: Props): JSX.Elemen
|
||||||
<NoContentNorFolderMessage />
|
<NoContentNorFolderMessage />
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
folder.contents?.data,
|
|
||||||
folder.parent_folder?.data?.attributes,
|
|
||||||
folder.slug,
|
|
||||||
folder.subfolders?.data,
|
|
||||||
folder.titles,
|
|
||||||
isContentPanelAtLeast4xl,
|
|
||||||
langui,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
@ -23,10 +22,9 @@ interface Props extends AppLayoutRequired {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
const testReport = useMemo(() => testingContent(contents), [contents]);
|
const testReport = testingContent(contents);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
{<h2 className="text-2xl">{testReport.title}</h2>}
|
{<h2 className="text-2xl">{testReport.title}</h2>}
|
||||||
|
|
||||||
|
@ -71,8 +69,6 @@ const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[testReport.lines, testReport.title]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
@ -27,8 +26,7 @@ interface Props extends AppLayoutRequired {
|
||||||
const CheckupLibraryItems = ({ libraryItems, ...otherProps }: Props): JSX.Element => {
|
const CheckupLibraryItems = ({ libraryItems, ...otherProps }: Props): JSX.Element => {
|
||||||
const testReport = testingLibraryItem(libraryItems);
|
const testReport = testingLibraryItem(libraryItems);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
{<h2 className="text-2xl">{testReport.title}</h2>}
|
{<h2 className="text-2xl">{testReport.title}</h2>}
|
||||||
|
|
||||||
|
@ -73,8 +71,6 @@ const CheckupLibraryItems = ({ libraryItems, ...otherProps }: Props): JSX.Elemen
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[testReport.lines, testReport.title]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
import TurndownService from "turndown";
|
import TurndownService from "turndown";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
@ -156,8 +156,7 @@ const Editor = (props: Props): JSX.Element => {
|
||||||
[transformationWrapper]
|
[transformationWrapper]
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<Popup isVisible={converterOpened} onCloseRequest={() => setConverterOpened(false)}>
|
<Popup isVisible={converterOpened} onCloseRequest={() => setConverterOpened(false)}>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
|
@ -257,8 +256,8 @@ const Editor = (props: Props): JSX.Element => {
|
||||||
<>
|
<>
|
||||||
<h3 className="text-lg">Transcripts</h3>
|
<h3 className="text-lg">Transcripts</h3>
|
||||||
<p>
|
<p>
|
||||||
Use this to create dialogues and transcripts. Start by adding a container, then
|
Use this to create dialogues and transcripts. Start by adding a container, then add
|
||||||
add transcript speech line within.
|
transcript speech line within.
|
||||||
</p>
|
</p>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<ToolTip
|
<ToolTip
|
||||||
|
@ -327,11 +326,7 @@ const Editor = (props: Props): JSX.Element => {
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
}>
|
}>
|
||||||
<Button
|
<Button onClick={() => wrap("IntraLink", {})} icon={Icon.Link} text={"Internal"} />
|
||||||
onClick={() => wrap("IntraLink", {})}
|
|
||||||
icon={Icon.Link}
|
|
||||||
text={"Internal"}
|
|
||||||
/>
|
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
<ToolTip
|
<ToolTip
|
||||||
placement="right"
|
placement="right"
|
||||||
|
@ -398,8 +393,6 @@ const Editor = (props: Props): JSX.Element => {
|
||||||
<TableOfContents text={markdown} />
|
<TableOfContents text={markdown} />
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[appendDoc, converterOpened, handleInput, insert, markdown, preline, toggleWrap, wrap]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} {...props} />;
|
return <AppLayout contentPanel={contentPanel} {...props} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
||||||
|
@ -359,8 +359,7 @@ const Transcript = (props: Props): JSX.Element => {
|
||||||
[updateDisplayedText]
|
[updateDisplayedText]
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full} className="overflow-hidden !pr-0 !pt-4">
|
<ContentPanel width={ContentPanelWidthSizes.Full} className="overflow-hidden !pr-0 !pt-4">
|
||||||
<div className="grid grid-flow-col grid-cols-[1fr_5rem]">
|
<div className="grid grid-flow-col grid-cols-[1fr_5rem]">
|
||||||
<textarea
|
<textarea
|
||||||
|
@ -522,20 +521,6 @@ const Transcript = (props: Props): JSX.Element => {
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
convertFullWidth,
|
|
||||||
convertPunctuation,
|
|
||||||
fontSize,
|
|
||||||
insert,
|
|
||||||
lineIndex,
|
|
||||||
text,
|
|
||||||
toggleDakuten,
|
|
||||||
toggleSmallForm,
|
|
||||||
updateDisplayedText,
|
|
||||||
updateLineIndex,
|
|
||||||
xOffset,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} {...props} contentPanelScroolbar={false} />;
|
return <AppLayout contentPanel={contentPanel} {...props} contentPanelScroolbar={false} />;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback } from "react";
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
|
@ -88,23 +88,15 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
|
||||||
useScrollTopOnChange(Ids.ContentPanel, [item]);
|
useScrollTopOnChange(Ids.ContentPanel, [item]);
|
||||||
const currentIntersection = useIntersectionList(intersectionIds);
|
const currentIntersection = useIntersectionList(intersectionIds);
|
||||||
|
|
||||||
const isVariantSet = useMemo(
|
const isVariantSet =
|
||||||
() =>
|
|
||||||
item.metadata?.[0]?.__typename === "ComponentMetadataGroup" &&
|
item.metadata?.[0]?.__typename === "ComponentMetadataGroup" &&
|
||||||
item.metadata[0].subtype?.data?.attributes?.slug === "variant-set",
|
item.metadata[0].subtype?.data?.attributes?.slug === "variant-set";
|
||||||
[item.metadata]
|
|
||||||
);
|
|
||||||
|
|
||||||
const displayOpenScans = useMemo(
|
const displayOpenScans = item.contents?.data.some(
|
||||||
() =>
|
|
||||||
item.contents?.data.some(
|
|
||||||
(content) => content.attributes?.scan_set && content.attributes.scan_set.length > 0
|
(content) => content.attributes?.scan_set && content.attributes.scan_set.length > 0
|
||||||
),
|
|
||||||
[item.contents?.data]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/library/" title={langui.library} displayOnlyOn="3ColumnsLayout" />
|
<ReturnButton href="/library/" title={langui.library} displayOnlyOn="3ColumnsLayout" />
|
||||||
|
|
||||||
|
@ -153,12 +145,9 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[currentIntersection, isVariantSet, item.contents, item.gallery, item.subitems, langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/library/"
|
href="/library/"
|
||||||
|
@ -203,9 +192,7 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
<div className="grid place-items-center text-center">
|
<div className="grid place-items-center text-center">
|
||||||
<h1 className="text-3xl">{item.title}</h1>
|
<h1 className="text-3xl">{item.title}</h1>
|
||||||
{isDefinedAndNotEmpty(item.subtitle) && (
|
{isDefinedAndNotEmpty(item.subtitle) && <h2 className="text-2xl">{item.subtitle}</h2>}
|
||||||
<h2 className="text-2xl">{item.subtitle}</h2>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!isUntangibleGroupItem(item.metadata?.[0]) && isDefinedAndNotEmpty(itemId) && (
|
{!isUntangibleGroupItem(item.metadata?.[0]) && isDefinedAndNotEmpty(itemId) && (
|
||||||
|
@ -562,37 +549,6 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
langui,
|
|
||||||
isContentPanelAtLeast3xl,
|
|
||||||
item.thumbnail?.data?.attributes,
|
|
||||||
item.subitem_of?.data,
|
|
||||||
item.title,
|
|
||||||
item.subtitle,
|
|
||||||
item.metadata,
|
|
||||||
item.descriptions,
|
|
||||||
item.urls,
|
|
||||||
item.gallery,
|
|
||||||
item.release_date,
|
|
||||||
item.price,
|
|
||||||
item.categories,
|
|
||||||
item.size,
|
|
||||||
item.subitems,
|
|
||||||
item.contents,
|
|
||||||
item.slug,
|
|
||||||
itemId,
|
|
||||||
router.locale,
|
|
||||||
currencies,
|
|
||||||
currency,
|
|
||||||
isContentPanelAtLeastSm,
|
|
||||||
isVariantSet,
|
|
||||||
hoverable,
|
|
||||||
toggleKeepInfoVisible,
|
|
||||||
keepInfoVisible,
|
|
||||||
displayOpenScans,
|
|
||||||
showLightBox,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
|
import { Fragment, useCallback, useEffect, useState } from "react";
|
||||||
import { useHotkeys } from "react-hotkeys-hook";
|
import { useHotkeys } from "react-hotkeys-hook";
|
||||||
import Slider from "rc-slider";
|
import Slider from "rc-slider";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
@ -44,6 +44,7 @@ import { useFullscreen } from "hooks/useFullscreen";
|
||||||
import { atoms } from "contexts/atoms";
|
import { atoms } from "contexts/atoms";
|
||||||
import { useAtomGetter } from "helpers/atoms";
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
import { FilterSettings, useReaderSettings } from "hooks/useReaderSettings";
|
import { FilterSettings, useReaderSettings } from "hooks/useReaderSettings";
|
||||||
|
import { useIsWebkit } from "hooks/useIsWebkit";
|
||||||
|
|
||||||
const CUSTOM_DARK_DROPSHADOW = `
|
const CUSTOM_DARK_DROPSHADOW = `
|
||||||
drop-shadow(0 0 0.5em rgb(var(--theme-color-shade) / 30%))
|
drop-shadow(0 0 0.5em rgb(var(--theme-color-shade) / 30%))
|
||||||
|
@ -112,19 +113,14 @@ const LibrarySlug = ({
|
||||||
is1ColumnLayout ? "single" : "double"
|
is1ColumnLayout ? "single" : "double"
|
||||||
);
|
);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const isWebkit = useIsWebkit();
|
||||||
|
|
||||||
const { isFullscreen, toggleFullscreen, requestFullscreen } = useFullscreen(Ids.ContentPanel);
|
const { isFullscreen, toggleFullscreen, requestFullscreen } = useFullscreen(Ids.ContentPanel);
|
||||||
|
|
||||||
const effectiveDisplayMode = useMemo(
|
const effectiveDisplayMode =
|
||||||
() =>
|
currentPageIndex === 0 || currentPageIndex === pages.length - 1 ? "single" : displayMode;
|
||||||
currentPageIndex === 0 || currentPageIndex === pages.length - 1 ? "single" : displayMode,
|
|
||||||
[currentPageIndex, displayMode, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const ajustedSidepagesTotalWidth = useMemo(
|
const ajustedSidepagesTotalWidth = pages.length * SIDEPAGES_PAGE_WIDTH * (120 / pageWidth);
|
||||||
() => pages.length * SIDEPAGES_PAGE_WIDTH * (120 / pageWidth),
|
|
||||||
[pageWidth, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const changeCurrentPageIndex = useCallback(
|
const changeCurrentPageIndex = useCallback(
|
||||||
(callbackFn: (current: number) => number) => {
|
(callbackFn: (current: number) => number) => {
|
||||||
|
@ -185,61 +181,39 @@ const LibrarySlug = ({
|
||||||
handlePageNavigation,
|
handlePageNavigation,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const firstPage = useMemo(
|
const firstPage =
|
||||||
() =>
|
|
||||||
pages[
|
pages[
|
||||||
effectiveDisplayMode === "double" && currentPageIndex % 2 === 0
|
effectiveDisplayMode === "double" && currentPageIndex % 2 === 0
|
||||||
? currentPageIndex - 1
|
? currentPageIndex - 1
|
||||||
: currentPageIndex
|
: currentPageIndex
|
||||||
],
|
];
|
||||||
[currentPageIndex, effectiveDisplayMode, pages]
|
|
||||||
);
|
const secondPage =
|
||||||
const secondPage = useMemo(
|
|
||||||
() =>
|
|
||||||
pages[
|
pages[
|
||||||
effectiveDisplayMode === "double" && currentPageIndex % 2 === 0
|
effectiveDisplayMode === "double" && currentPageIndex % 2 === 0
|
||||||
? currentPageIndex
|
? currentPageIndex
|
||||||
: currentPageIndex + 1
|
: currentPageIndex + 1
|
||||||
],
|
];
|
||||||
[currentPageIndex, effectiveDisplayMode, pages]
|
|
||||||
);
|
|
||||||
|
|
||||||
const leftSidePagesCount = useMemo(
|
const leftSidePagesCount =
|
||||||
() =>
|
pageOrder === PageOrder.LeftToRight ? currentPageIndex : pages.length - 1 - currentPageIndex;
|
||||||
pageOrder === PageOrder.LeftToRight ? currentPageIndex : pages.length - 1 - currentPageIndex,
|
|
||||||
[currentPageIndex, pageOrder, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const rightSidePagesCount = useMemo(
|
const rightSidePagesCount =
|
||||||
() =>
|
pageOrder === PageOrder.LeftToRight ? pages.length - 1 - currentPageIndex : currentPageIndex;
|
||||||
pageOrder === PageOrder.LeftToRight ? pages.length - 1 - currentPageIndex : currentPageIndex,
|
|
||||||
[currentPageIndex, pageOrder, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const leftSidePagesWidth = useMemo(
|
const leftSidePagesWidth = `${
|
||||||
() =>
|
|
||||||
`${
|
|
||||||
pageOrder === PageOrder.LeftToRight
|
pageOrder === PageOrder.LeftToRight
|
||||||
? (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
? (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
||||||
: ajustedSidepagesTotalWidth -
|
: ajustedSidepagesTotalWidth - (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
||||||
(currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
}vmin`;
|
||||||
}vmin`,
|
|
||||||
[ajustedSidepagesTotalWidth, currentPageIndex, pageOrder, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const rightSidePagesWidth = useMemo(
|
const rightSidePagesWidth = `${
|
||||||
() =>
|
|
||||||
`${
|
|
||||||
pageOrder === PageOrder.LeftToRight
|
pageOrder === PageOrder.LeftToRight
|
||||||
? ajustedSidepagesTotalWidth -
|
? ajustedSidepagesTotalWidth - (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
||||||
(currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
|
||||||
: (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
: (currentPageIndex / pages.length) * ajustedSidepagesTotalWidth
|
||||||
}vmin`,
|
}vmin`;
|
||||||
[ajustedSidepagesTotalWidth, currentPageIndex, pageOrder, pages.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const leftSideClipPath = useMemo(
|
const leftSideClipPath = `polygon(
|
||||||
() => `polygon(
|
|
||||||
${
|
${
|
||||||
isSidePagesEnabled
|
isSidePagesEnabled
|
||||||
? `
|
? `
|
||||||
|
@ -265,12 +239,9 @@ const LibrarySlug = ({
|
||||||
: "101% 0%, 101% 100%,"
|
: "101% 0%, 101% 100%,"
|
||||||
}
|
}
|
||||||
70% 100%
|
70% 100%
|
||||||
)`,
|
)`;
|
||||||
[filterSettings.bookFold, isSidePagesEnabled, leftSidePagesWidth]
|
|
||||||
);
|
|
||||||
|
|
||||||
const rightSideClipPath = useMemo(
|
const rightSideClipPath = `polygon(
|
||||||
() => `polygon(
|
|
||||||
${
|
${
|
||||||
isSidePagesEnabled
|
isSidePagesEnabled
|
||||||
? `calc(100% - ${rightSidePagesWidth}) 0%,
|
? `calc(100% - ${rightSidePagesWidth}) 0%,
|
||||||
|
@ -295,17 +266,11 @@ const LibrarySlug = ({
|
||||||
: "-1% 100%, -1% 0%,"
|
: "-1% 100%, -1% 0%,"
|
||||||
}
|
}
|
||||||
30% 0%
|
30% 0%
|
||||||
)`,
|
)`;
|
||||||
[filterSettings.bookFold, isSidePagesEnabled, rightSidePagesWidth]
|
|
||||||
);
|
|
||||||
|
|
||||||
const pageHeight = useMemo(
|
const pageHeight = `calc(100vh - ${is1ColumnLayout ? 5 : 4}rem - 3rem)`;
|
||||||
() => `calc(100vh - ${is1ColumnLayout ? 5 : 4}rem - 3rem)`,
|
|
||||||
[is1ColumnLayout]
|
|
||||||
);
|
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton title={langui.item} href={`/library/${itemSlug}`} />
|
<ReturnButton title={langui.item} href={`/library/${itemSlug}`} />
|
||||||
|
|
||||||
|
@ -326,9 +291,11 @@ const LibrarySlug = ({
|
||||||
<Switch value={isSidePagesEnabled} onClick={toggleIsSidePagesEnabled} />
|
<Switch value={isSidePagesEnabled} onClick={toggleIsSidePagesEnabled} />
|
||||||
</WithLabel>
|
</WithLabel>
|
||||||
|
|
||||||
|
{!isWebkit && (
|
||||||
<WithLabel label={langui.shadow}>
|
<WithLabel label={langui.shadow}>
|
||||||
<Switch value={filterSettings.dropShadow} onClick={toggleDropShadow} />
|
<Switch value={filterSettings.dropShadow} onClick={toggleDropShadow} />
|
||||||
</WithLabel>
|
</WithLabel>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4 grid">
|
<div className="mt-4 grid">
|
||||||
|
@ -398,44 +365,9 @@ const LibrarySlug = ({
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
langui.item,
|
|
||||||
langui.paper_texture,
|
|
||||||
langui.book_fold,
|
|
||||||
langui.lighting,
|
|
||||||
langui.side_pages,
|
|
||||||
langui.shadow,
|
|
||||||
langui.night_reader,
|
|
||||||
langui.reading_layout,
|
|
||||||
langui.single_page_view,
|
|
||||||
langui.double_page_view,
|
|
||||||
langui.quality,
|
|
||||||
langui.reset_all_options,
|
|
||||||
itemSlug,
|
|
||||||
filterSettings.paperTexture,
|
|
||||||
filterSettings.bookFold,
|
|
||||||
filterSettings.lighting,
|
|
||||||
filterSettings.dropShadow,
|
|
||||||
filterSettings.teint,
|
|
||||||
togglePaperTexture,
|
|
||||||
toggleBookFold,
|
|
||||||
toggleLighting,
|
|
||||||
isSidePagesEnabled,
|
|
||||||
toggleIsSidePagesEnabled,
|
|
||||||
toggleDropShadow,
|
|
||||||
displayMode,
|
|
||||||
pageQuality,
|
|
||||||
setTeint,
|
|
||||||
changeDisplayMode,
|
|
||||||
setPageQuality,
|
|
||||||
resetReaderSettings,
|
|
||||||
is1ColumnLayout,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full} className="grid place-content-center !p-0">
|
<ContentPanel width={ContentPanelWidthSizes.Full} className="grid place-content-center !p-0">
|
||||||
<div className={cJoin("mb-12 grid", cIf(is1ColumnLayout, "!p-0", "!p-8"))}>
|
<div className={cJoin("mb-12 grid", cIf(is1ColumnLayout, "!p-0", "!p-8"))}>
|
||||||
<TransformWrapper
|
<TransformWrapper
|
||||||
|
@ -451,11 +383,12 @@ const LibrarySlug = ({
|
||||||
gridAutoFlow: "column",
|
gridAutoFlow: "column",
|
||||||
display: "grid",
|
display: "grid",
|
||||||
placeContent: "center",
|
placeContent: "center",
|
||||||
filter: filterSettings.dropShadow
|
filter:
|
||||||
? isDarkMode
|
!filterSettings.dropShadow || isWebkit
|
||||||
|
? undefined
|
||||||
|
: isDarkMode
|
||||||
? CUSTOM_DARK_DROPSHADOW
|
? CUSTOM_DARK_DROPSHADOW
|
||||||
: CUSTOM_LIGHT_DROPSHADOW
|
: CUSTOM_LIGHT_DROPSHADOW,
|
||||||
: undefined,
|
|
||||||
}}>
|
}}>
|
||||||
{effectiveDisplayMode === "single" ? (
|
{effectiveDisplayMode === "single" ? (
|
||||||
<div
|
<div
|
||||||
|
@ -625,36 +558,6 @@ const LibrarySlug = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
is1ColumnLayout,
|
|
||||||
currentZoom,
|
|
||||||
filterSettings,
|
|
||||||
isDarkMode,
|
|
||||||
pageHeight,
|
|
||||||
effectiveDisplayMode,
|
|
||||||
firstPage,
|
|
||||||
pageQuality,
|
|
||||||
bookType,
|
|
||||||
leftSideClipPath,
|
|
||||||
isSidePagesEnabled,
|
|
||||||
leftSidePagesWidth,
|
|
||||||
leftSidePagesCount,
|
|
||||||
pageOrder,
|
|
||||||
secondPage,
|
|
||||||
rightSideClipPath,
|
|
||||||
rightSidePagesWidth,
|
|
||||||
rightSidePagesCount,
|
|
||||||
isGalleryMode,
|
|
||||||
currentPageIndex,
|
|
||||||
pages.length,
|
|
||||||
isFullscreen,
|
|
||||||
toggleFullscreen,
|
|
||||||
item.contents?.data,
|
|
||||||
item.slug,
|
|
||||||
handlePageNavigation,
|
|
||||||
changeCurrentPageIndex,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -798,9 +701,9 @@ interface PageFiltersProps {
|
||||||
|
|
||||||
const PageFilters = ({ page, bookType, options }: PageFiltersProps) => {
|
const PageFilters = ({ page, bookType, options }: PageFiltersProps) => {
|
||||||
const isDarkMode = useAtomGetter(atoms.settings.darkMode);
|
const isDarkMode = useAtomGetter(atoms.settings.darkMode);
|
||||||
const commonCss = useMemo(
|
const commonCss = cJoin(
|
||||||
() => cJoin("absolute inset-0", cIf(page === "right", "[background-position-x:-100%]")),
|
"absolute inset-0",
|
||||||
[page]
|
cIf(page === "right", "[background-position-x:-100%]")
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -929,10 +832,7 @@ const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps):
|
||||||
}, []),
|
}, []),
|
||||||
});
|
});
|
||||||
|
|
||||||
const pages = useMemo(
|
const pages = filterHasAttributes(selectedScan?.pages?.data, ["attributes"]);
|
||||||
() => filterHasAttributes(selectedScan?.pages?.data, ["attributes"]),
|
|
||||||
[selectedScan]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useState, useMemo, useCallback } from "react";
|
import { useState, useCallback } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
|
@ -222,8 +222,7 @@ const Library = ({ items, ...otherProps }: Props): JSX.Element => {
|
||||||
[groupingMethod, langui]
|
[groupingMethod, langui]
|
||||||
);
|
);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.LibraryBooks}
|
icon={Icon.LibraryBooks}
|
||||||
|
@ -387,31 +386,9 @@ const Library = ({ items, ...otherProps }: Props): JSX.Element => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
filterUserStatus,
|
|
||||||
groupingMethod,
|
|
||||||
hoverable,
|
|
||||||
keepInfoVisible,
|
|
||||||
langui,
|
|
||||||
searchName,
|
|
||||||
setKeepInfoVisible,
|
|
||||||
setShowPrimaryItems,
|
|
||||||
setShowSecondaryItems,
|
|
||||||
setShowSubitems,
|
|
||||||
showPrimaryItems,
|
|
||||||
showSecondaryItems,
|
|
||||||
showSubitems,
|
|
||||||
sortingMethod,
|
|
||||||
toggleKeepInfoVisible,
|
|
||||||
toggleShowPrimaryItems,
|
|
||||||
toggleShowSecondaryItems,
|
|
||||||
toggleShowSubitems,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(items, ["id", "attributes"] as const)}
|
items={filterHasAttributes(items, ["id", "attributes"] as const)}
|
||||||
|
@ -461,16 +438,6 @@ const Library = ({ items, ...otherProps }: Props): JSX.Element => {
|
||||||
paginationItemPerPage={25}
|
paginationItemPerPage={25}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
filteringFunction,
|
|
||||||
groupingFunction,
|
|
||||||
isContentPanelAtLeast4xl,
|
|
||||||
items,
|
|
||||||
keepInfoVisible,
|
|
||||||
searchName,
|
|
||||||
sortingFunction,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo, useState } from "react";
|
import { useState } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
|
@ -58,8 +58,7 @@ const News = ({ posts, ...otherProps }: Props): JSX.Element => {
|
||||||
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
||||||
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader icon={Icon.Feed} title={langui.news} description={langui.news_description} />
|
<PanelHeader icon={Icon.Feed} title={langui.news} description={langui.news_description} />
|
||||||
|
|
||||||
|
@ -102,12 +101,9 @@ const News = ({ posts, ...otherProps }: Props): JSX.Element => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[hoverable, keepInfoVisible, langui, searchName, setKeepInfoVisible, toggleKeepInfoVisible]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(posts, ["attributes", "id"] as const)}
|
items={filterHasAttributes(posts, ["attributes", "id"] as const)}
|
||||||
|
@ -151,8 +147,6 @@ const News = ({ posts, ...otherProps }: Props): JSX.Element => {
|
||||||
paginationItemPerPage={25}
|
paginationItemPerPage={25}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[keepInfoVisible, posts, searchName, isContentPanelAtLeast4xl]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isTerminalMode) {
|
if (isTerminalMode) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback } from "react";
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
|
@ -49,17 +49,13 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
});
|
});
|
||||||
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href={`/wiki`} title={langui.wiki} displayOnlyOn={"3ColumnsLayout"} />
|
<ReturnButton href={`/wiki`} title={langui.wiki} displayOnlyOn={"3ColumnsLayout"} />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Large}>
|
<ContentPanel width={ContentPanelWidthSizes.Large}>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href={`/wiki`}
|
href={`/wiki`}
|
||||||
|
@ -173,22 +169,6 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
LanguageSwitcher,
|
|
||||||
is3ColumnsLayout,
|
|
||||||
languageSwitcherProps,
|
|
||||||
langui.categories,
|
|
||||||
langui.summary,
|
|
||||||
langui.tags,
|
|
||||||
langui.wiki,
|
|
||||||
page.categories?.data,
|
|
||||||
page.definitions,
|
|
||||||
page.tags?.data,
|
|
||||||
page.thumbnail?.data?.attributes,
|
|
||||||
selectedTranslation,
|
|
||||||
showLightBox,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isTerminalMode) {
|
if (isTerminalMode) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { InsetBox } from "components/Containers/InsetBox";
|
import { InsetBox } from "components/Containers/InsetBox";
|
||||||
|
@ -46,18 +46,13 @@ interface Props extends AppLayoutRequired {
|
||||||
|
|
||||||
const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => {
|
const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => {
|
||||||
const langui = useAtomGetter(atoms.localData.langui);
|
const langui = useAtomGetter(atoms.localData.langui);
|
||||||
const ids = useMemo(
|
const ids = filterHasAttributes(chronologyEras, ["attributes"] as const).map(
|
||||||
() =>
|
|
||||||
filterHasAttributes(chronologyEras, ["attributes"] as const).map(
|
|
||||||
(era) => era.attributes.slug
|
(era) => era.attributes.slug
|
||||||
),
|
|
||||||
[chronologyEras]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentIntersection = useIntersectionList(ids);
|
const currentIntersection = useIntersectionList(ids);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/wiki" title={langui.wiki} displayOnlyOn="3ColumnsLayout" />
|
<ReturnButton href="/wiki" title={langui.wiki} displayOnlyOn="3ColumnsLayout" />
|
||||||
|
|
||||||
|
@ -84,12 +79,9 @@ const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props):
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[chronologyEras, currentIntersection, langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/wiki"
|
href="/wiki"
|
||||||
|
@ -118,8 +110,6 @@ const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props):
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[chronologyEras, chronologyItems, langui]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
|
||||||
|
@ -161,7 +151,7 @@ interface ChronologyEraProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChronologyEra = ({ id, title, description, chronologyItems }: ChronologyEraProps) => {
|
const ChronologyEra = ({ id, title, description, chronologyItems }: ChronologyEraProps) => {
|
||||||
const yearGroups = useMemo(() => {
|
const yearGroups = (() => {
|
||||||
const memo: Props["chronologyItems"][] = [];
|
const memo: Props["chronologyItems"][] = [];
|
||||||
let currentYear = -Infinity;
|
let currentYear = -Infinity;
|
||||||
filterHasAttributes(chronologyItems, ["attributes"] as const).forEach((item) => {
|
filterHasAttributes(chronologyItems, ["attributes"] as const).forEach((item) => {
|
||||||
|
@ -173,7 +163,7 @@ const ChronologyEra = ({ id, title, description, chronologyItems }: ChronologyEr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return memo;
|
return memo;
|
||||||
}, [chronologyItems]);
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id={id}>
|
<div id={id}>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { useBoolean } from "usehooks-ts";
|
import { useBoolean } from "usehooks-ts";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
|
@ -67,8 +67,7 @@ const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => {
|
||||||
setValue: setKeepInfoVisible,
|
setValue: setKeepInfoVisible,
|
||||||
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = (
|
||||||
() => (
|
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon={Icon.TravelExplore}
|
icon={Icon.TravelExplore}
|
||||||
|
@ -135,16 +134,6 @@ const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
<NavOption title={langui.chronology} url="/wiki/chronology" border />
|
<NavOption title={langui.chronology} url="/wiki/chronology" border />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
|
||||||
[
|
|
||||||
groupingMethod,
|
|
||||||
hoverable,
|
|
||||||
keepInfoVisible,
|
|
||||||
langui,
|
|
||||||
searchName,
|
|
||||||
setKeepInfoVisible,
|
|
||||||
toggleKeepInfoVisible,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupingFunction = useCallback(
|
const groupingFunction = useCallback(
|
||||||
|
@ -172,8 +161,7 @@ const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => {
|
||||||
[groupingMethod, langui]
|
[groupingMethod, langui]
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = useMemo(
|
const contentPanel = (
|
||||||
() => (
|
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(pages, ["id", "attributes"] as const)}
|
items={filterHasAttributes(pages, ["id", "attributes"] as const)}
|
||||||
|
@ -198,9 +186,7 @@ const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => {
|
||||||
thumbnailRounded
|
thumbnailRounded
|
||||||
thumbnailForceAspectRatio
|
thumbnailForceAspectRatio
|
||||||
keepInfoVisible={keepInfoVisible}
|
keepInfoVisible={keepInfoVisible}
|
||||||
topChips={filterHasAttributes(item.attributes.tags?.data, [
|
topChips={filterHasAttributes(item.attributes.tags?.data, ["attributes"] as const).map(
|
||||||
"attributes",
|
|
||||||
] as const).map(
|
|
||||||
(tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
(tag) => tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
||||||
)}
|
)}
|
||||||
bottomChips={filterHasAttributes(item.attributes.categories?.data, [
|
bottomChips={filterHasAttributes(item.attributes.categories?.data, [
|
||||||
|
@ -228,8 +214,6 @@ const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => {
|
||||||
paginationItemPerPage={25}
|
paginationItemPerPage={25}
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
),
|
|
||||||
[groupingFunction, keepInfoVisible, pages, searchName, isContentPanelAtLeast4xl]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isTerminalMode) {
|
if (isTerminalMode) {
|
||||||
|
|
|
@ -249,6 +249,21 @@ module.exports = {
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/* Webkit fixes */
|
||||||
|
plugin(({ addUtilities }) => {
|
||||||
|
addUtilities({
|
||||||
|
".webkit-fixes": {
|
||||||
|
"*": {
|
||||||
|
"--tw-drop-shadow": "unset !important",
|
||||||
|
"--tw-shadow": "unset !important",
|
||||||
|
},
|
||||||
|
".texture-paper-dots": {
|
||||||
|
backgroundImage: "unset !important",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
/* Add support for break-wrods CSS attribute */
|
/* Add support for break-wrods CSS attribute */
|
||||||
plugin(({ addUtilities }) => {
|
plugin(({ addUtilities }) => {
|
||||||
addUtilities({
|
addUtilities({
|
||||||
|
|
Loading…
Reference in New Issue