load pattern
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
|
||||
import { useGetAbout } from "@/app/[name]/(Main)/about/hooks/useAboutData";
|
||||
import {
|
||||
applyPatternCssVariables,
|
||||
clearPatternCssVariables,
|
||||
colorizeSvg,
|
||||
hexToRgba,
|
||||
isPatternBackground,
|
||||
PATTERN_BACKGROUND_OPACITY,
|
||||
} from "@/lib/helpers/backgroundUtils";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
const DEFAULT_MENU_COLOR = "#1E3A8A";
|
||||
|
||||
export default function AppBackground() {
|
||||
const { name: restaurantSlug } = useParams<{ name: string }>();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const restaurant = aboutData?.data;
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [patternImageUrl, setPatternImageUrl] = useState<string | null>(null);
|
||||
const blobUrlRef = useRef<string | null>(null);
|
||||
|
||||
const isPattern = restaurant ? isPatternBackground(restaurant) : false;
|
||||
const menuColor = restaurant?.menuColor || DEFAULT_MENU_COLOR;
|
||||
const baseTint = hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const revokeBlobUrl = () => {
|
||||
if (blobUrlRef.current) {
|
||||
URL.revokeObjectURL(blobUrlRef.current);
|
||||
blobUrlRef.current = null;
|
||||
}
|
||||
setPatternImageUrl(null);
|
||||
};
|
||||
|
||||
if (!isPattern || !restaurant?.bgUrl || !restaurantSlug) {
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
return;
|
||||
}
|
||||
|
||||
applyPatternCssVariables(menuColor);
|
||||
|
||||
let cancelled = false;
|
||||
const proxyUrl = `/${restaurantSlug}/api/proxy-svg?url=${encodeURIComponent(restaurant.bgUrl)}`;
|
||||
|
||||
fetch(proxyUrl)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch background pattern");
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then((svg) => {
|
||||
if (cancelled) return;
|
||||
|
||||
revokeBlobUrl();
|
||||
const blob = new Blob([colorizeSvg(svg, menuColor)], {
|
||||
type: "image/svg+xml;charset=utf-8",
|
||||
});
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
blobUrlRef.current = blobUrl;
|
||||
setPatternImageUrl(blobUrl);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
revokeBlobUrl();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
};
|
||||
}, [isPattern, menuColor, restaurant?.bgUrl, restaurantSlug]);
|
||||
|
||||
if (!mounted || !isPattern) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
aria-hidden
|
||||
className="fixed inset-0 pointer-events-none"
|
||||
style={{
|
||||
zIndex: 0,
|
||||
backgroundColor: baseTint,
|
||||
...(patternImageUrl
|
||||
? {
|
||||
backgroundImage: `url("${patternImageUrl}")`,
|
||||
backgroundRepeat: "repeat",
|
||||
backgroundSize: "auto",
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
/>,
|
||||
document.body,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user