import Head from "next/head"; import { useSwipeable } from "react-swipeable"; import { MaterialSymbol } from "material-symbols"; import { layout } from "../../design.config"; import { Ico } from "./Ico"; import { MainPanel } from "./Panels/MainPanel"; import { isDefined, isUndefined } from "helpers/asserts"; import { cIf, cJoin } from "helpers/className"; import { OpenGraph, TITLE_PREFIX, TITLE_SEPARATOR } from "helpers/openGraph"; import { Ids } from "types/ids"; import { atoms } from "contexts/atoms"; import { useAtomGetter, useAtomPair } from "helpers/atoms"; import { useFormat } from "hooks/useFormat"; /* * ╭─────────────╮ * ────────────────────────────────────────╯ CONSTANTS ╰────────────────────────────────────────── */ const SENSIBILITY_SWIPE = 1.1; /* * ╭─────────────╮ * ───────────────────────────────────────╯ COMPONENT ╰─────────────────────────────────────────── */ export interface AppLayoutRequired { openGraph: OpenGraph; } interface Props extends AppLayoutRequired { subPanel?: React.ReactNode; subPanelIcon?: MaterialSymbol; contentPanel?: React.ReactNode; contentPanelScroolbar?: boolean; } // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const AppLayout = ({ subPanel, contentPanel, openGraph, subPanelIcon = "tune", contentPanelScroolbar = true, }: Props): JSX.Element => { const isMainPanelReduced = useAtomGetter(atoms.layout.mainPanelReduced); const [isSubPanelOpened, setSubPanelOpened] = useAtomPair(atoms.layout.subPanelOpened); const [isMainPanelOpened, setMainPanelOpened] = useAtomPair(atoms.layout.mainPanelOpened); const isMenuGesturesEnabled = useAtomGetter(atoms.layout.menuGesturesEnabled); const { format } = useFormat(); const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout); const isScreenAtLeastXs = useAtomGetter(atoms.containerQueries.isScreenAtLeastXs); const handlers = useSwipeable({ onSwipedLeft: (SwipeEventData) => { if (isMenuGesturesEnabled) { if (SwipeEventData.velocity < SENSIBILITY_SWIPE) return; if (isMainPanelOpened) { setMainPanelOpened(false); } else if (isDefined(subPanel) && isDefined(contentPanel)) { setSubPanelOpened(true); } } }, onSwipedRight: (SwipeEventData) => { if (isMenuGesturesEnabled) { if (SwipeEventData.velocity < SENSIBILITY_SWIPE) return; if (isSubPanelOpened) { setSubPanelOpened(false); } else { setMainPanelOpened(true); } } }, }); const turnSubIntoContent = isDefined(subPanel) && isUndefined(contentPanel) && is1ColumnLayout; return (
30, "max-h-14 text-xl", "max-h-16 text-2xl") )}> {openGraph.title.substring(TITLE_PREFIX.length + TITLE_SEPARATOR.length) ? openGraph.title.substring(TITLE_PREFIX.length + TITLE_SEPARATOR.length) : "Accord’s Library"}
{isDefined(subPanel) && !turnSubIntoContent && ({message}