Fixed the anchor link problems, maybe
This commit is contained in:
parent
c464cb1402
commit
bd0185358c
|
@ -14,6 +14,7 @@ import { Currencies, Languages, Langui } from "helpers/localData";
|
||||||
import { useCurrencies, useLanguages, useLangui } from "hooks/useLocalData";
|
import { useCurrencies, useLanguages, useLangui } from "hooks/useLocalData";
|
||||||
import { getDefaultPreferredLanguages } from "helpers/locales";
|
import { getDefaultPreferredLanguages } from "helpers/locales";
|
||||||
import { useStateWithLocalStorage } from "hooks/useStateWithLocalStorage";
|
import { useStateWithLocalStorage } from "hooks/useStateWithLocalStorage";
|
||||||
|
import { useScrollIntoView } from "hooks/useScrollIntoView";
|
||||||
|
|
||||||
interface AppLayoutState {
|
interface AppLayoutState {
|
||||||
subPanelOpen: boolean;
|
subPanelOpen: boolean;
|
||||||
|
@ -301,12 +302,14 @@ export const AppContextProvider = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
router.events.on("routeChangeStart", () => {
|
router.events.on("routeChangeStart", () => {
|
||||||
|
console.log("[Router Events] on routeChangeStart");
|
||||||
setConfigPanelOpen(false);
|
setConfigPanelOpen(false);
|
||||||
setMainPanelOpen(false);
|
setMainPanelOpen(false);
|
||||||
setSubPanelOpen(false);
|
setSubPanelOpen(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.events.on("hashChangeStart", () => {
|
router.events.on("hashChangeStart", () => {
|
||||||
|
console.log("[Router Events] on hashChangeStart");
|
||||||
setSubPanelOpen(false);
|
setSubPanelOpen(false);
|
||||||
});
|
});
|
||||||
}, [router.events, setConfigPanelOpen, setMainPanelOpen, setSubPanelOpen]);
|
}, [router.events, setConfigPanelOpen, setMainPanelOpen, setSubPanelOpen]);
|
||||||
|
@ -317,6 +320,8 @@ export const AppContextProvider = (props: Props): JSX.Element => {
|
||||||
}%`;
|
}%`;
|
||||||
}, [fontSize]);
|
}, [fontSize]);
|
||||||
|
|
||||||
|
useScrollIntoView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider
|
<AppContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|
|
@ -5,6 +5,11 @@ export enum ImageQuality {
|
||||||
Og = "og",
|
Og = "og",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ImageProperties {
|
||||||
|
maxSize: number;
|
||||||
|
extension: "jpg" | "webp";
|
||||||
|
}
|
||||||
|
|
||||||
export interface OgImage {
|
export interface OgImage {
|
||||||
image: string;
|
image: string;
|
||||||
width: number;
|
width: number;
|
||||||
|
@ -12,6 +17,13 @@ export interface OgImage {
|
||||||
alt: string;
|
alt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const imageQualityProperties: Record<ImageQuality, ImageProperties> = {
|
||||||
|
small: { maxSize: 512, extension: "webp" },
|
||||||
|
medium: { maxSize: 1024, extension: "webp" },
|
||||||
|
large: { maxSize: 2048, extension: "webp" },
|
||||||
|
og: { maxSize: 512, extension: "jpg" },
|
||||||
|
};
|
||||||
|
|
||||||
export const getAssetFilename = (path: string): string => {
|
export const getAssetFilename = (path: string): string => {
|
||||||
let result = path.split("/");
|
let result = path.split("/");
|
||||||
result = result[result.length - 1].split(".");
|
result = result[result.length - 1].split(".");
|
||||||
|
@ -23,13 +35,13 @@ export const getAssetFilename = (path: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAssetURL = (url: string, quality: ImageQuality): string => {
|
export const getAssetURL = (url: string, quality: ImageQuality): string => {
|
||||||
let newUrl = url;
|
const indexEndPath = url.indexOf("/uploads/") + "/uploads/".length;
|
||||||
newUrl = newUrl.replace(/^\/uploads/u, `/${quality}`);
|
const indexStartExtension = url.lastIndexOf(".");
|
||||||
newUrl = newUrl.replace(/.jpg$/u, ".webp");
|
const assetPathWithoutExtension = url.slice(
|
||||||
newUrl = newUrl.replace(/.jpeg$/u, ".webp");
|
indexEndPath,
|
||||||
newUrl = newUrl.replace(/.png$/u, ".webp");
|
indexStartExtension
|
||||||
if (quality === ImageQuality.Og) newUrl = newUrl.replace(/.webp$/u, ".jpg");
|
);
|
||||||
return process.env.NEXT_PUBLIC_URL_IMG + newUrl;
|
return `${process.env.NEXT_PUBLIC_URL_IMG}/${quality}/${assetPathWithoutExtension}.${imageQualityProperties[quality].extension}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getImgSizesByMaxSize = (
|
const getImgSizesByMaxSize = (
|
||||||
|
@ -49,17 +61,5 @@ export const getImgSizesByQuality = (
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
quality: ImageQuality
|
quality: ImageQuality
|
||||||
): { width: number; height: number } => {
|
): { width: number; height: number } =>
|
||||||
switch (quality) {
|
getImgSizesByMaxSize(width, height, imageQualityProperties[quality].maxSize);
|
||||||
case ImageQuality.Og:
|
|
||||||
return getImgSizesByMaxSize(width, height, 512);
|
|
||||||
case ImageQuality.Small:
|
|
||||||
return getImgSizesByMaxSize(width, height, 512);
|
|
||||||
case ImageQuality.Medium:
|
|
||||||
return getImgSizesByMaxSize(width, height, 1024);
|
|
||||||
case ImageQuality.Large:
|
|
||||||
return getImgSizesByMaxSize(width, height, 2048);
|
|
||||||
default:
|
|
||||||
return { width: 0, height: 0 };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useMemo, useCallback, useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useIsClient } from "usehooks-ts";
|
import { useIsClient } from "usehooks-ts";
|
||||||
import { isDefined } from "helpers/others";
|
import { isDefined } from "helpers/others";
|
||||||
|
|
||||||
|
@ -7,23 +7,19 @@ export const useOnResize = (
|
||||||
onResize: (width: number, height: number) => void
|
onResize: (width: number, height: number) => void
|
||||||
): void => {
|
): void => {
|
||||||
const isClient = useIsClient();
|
const isClient = useIsClient();
|
||||||
const elem = useMemo(
|
|
||||||
() => (isClient ? document.querySelector(`#${id}`) : null),
|
|
||||||
[id, isClient]
|
|
||||||
);
|
|
||||||
|
|
||||||
const listener = useCallback(() => {
|
|
||||||
console.log("useOnResize");
|
|
||||||
if (elem?.clientWidth && elem.clientHeight) {
|
|
||||||
onResize(elem.clientWidth, elem.clientHeight);
|
|
||||||
}
|
|
||||||
}, [elem?.clientHeight, elem?.clientWidth, onResize]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const ro = new ResizeObserver(listener);
|
console.log("[useOnResize]", id);
|
||||||
|
const elem = isClient ? document.querySelector(`#${id}`) : null;
|
||||||
|
const ro = new ResizeObserver((resizeObserverEntry) =>
|
||||||
|
onResize(
|
||||||
|
resizeObserverEntry[0].contentRect.width,
|
||||||
|
resizeObserverEntry[0].contentRect.height
|
||||||
|
)
|
||||||
|
);
|
||||||
if (isDefined(elem)) {
|
if (isDefined(elem)) {
|
||||||
ro.observe(elem);
|
ro.observe(elem);
|
||||||
}
|
}
|
||||||
return () => ro.disconnect();
|
return () => ro.disconnect();
|
||||||
}, [elem, listener]);
|
}, [id, isClient, onResize]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useBoolean, useCounter } from "usehooks-ts";
|
||||||
|
import { isDefined } from "helpers/others";
|
||||||
|
|
||||||
|
export const useScrollIntoView = (): void => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { count, increment } = useCounter(0);
|
||||||
|
const { value: hasReachedElem, setTrue: setHasReachedElem } = useBoolean();
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasReachedElem) {
|
||||||
|
const indexHash = router.asPath.indexOf("#");
|
||||||
|
if (indexHash > 0) {
|
||||||
|
const hash = router.asPath.slice(indexHash + 1);
|
||||||
|
const element = document.getElementById(hash);
|
||||||
|
console.log(element);
|
||||||
|
if (isDefined(element)) {
|
||||||
|
console.log(`[useScrollIntoView] ${hash} found`);
|
||||||
|
element.scrollIntoView();
|
||||||
|
setHasReachedElem();
|
||||||
|
} else {
|
||||||
|
console.log(`[useScrollIntoView] ${hash} not found`);
|
||||||
|
setTimeout(() => {
|
||||||
|
increment();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [increment, router.asPath, count, hasReachedElem, setHasReachedElem]);
|
||||||
|
};
|
|
@ -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, useEffect, useMemo } from "react";
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
||||||
import {
|
import {
|
||||||
|
|
Loading…
Reference in New Issue