Cache
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { getThemeBootScript } from "@/lib/helpers/themeBootScript";
|
||||
|
||||
export function ThemeBootScript() {
|
||||
return (
|
||||
<script
|
||||
id="theme-boot"
|
||||
dangerouslySetInnerHTML={{ __html: getThemeBootScript() }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useLayoutEffect } from 'react'
|
||||
import { hexToOklch, calculateBrightness } from '@/lib/helpers/colorUtils'
|
||||
import { getCachedMenuColor, getRestaurantSlugFromPath, getThemeCache, applyCachedThemeToDom } from '@/lib/helpers/themeCache'
|
||||
|
||||
export function ThemeColorSetter() {
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
try {
|
||||
const savedColor = localStorage.getItem('theme-primary-color')
|
||||
const slug = getRestaurantSlugFromPath()
|
||||
const cachedTheme = slug ? getThemeCache(slug) : null
|
||||
if (cachedTheme) {
|
||||
applyCachedThemeToDom(cachedTheme)
|
||||
return
|
||||
}
|
||||
|
||||
const savedColor = getCachedMenuColor(slug)
|
||||
if (savedColor) {
|
||||
const oklchColor = hexToOklch(savedColor)
|
||||
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
"use client";
|
||||
|
||||
import { usePatternBackground } from "@/components/background/PatternBackgroundProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { THEME_BG_ELEMENT_ID } from "@/lib/helpers/themeCache";
|
||||
import { useLayoutEffect } from "react";
|
||||
|
||||
export default function AppBackground() {
|
||||
const { isPattern, backgroundStyle } = usePatternBackground();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
useLayoutEffect(() => {
|
||||
if (!isPattern) {
|
||||
document.getElementById(THEME_BG_ELEMENT_ID)?.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mounted || !isPattern) {
|
||||
return null;
|
||||
}
|
||||
let element = document.getElementById(THEME_BG_ELEMENT_ID);
|
||||
if (!element) {
|
||||
element = document.createElement("div");
|
||||
element.id = THEME_BG_ELEMENT_ID;
|
||||
element.setAttribute("aria-hidden", "true");
|
||||
element.style.position = "fixed";
|
||||
element.style.inset = "0";
|
||||
element.style.pointerEvents = "none";
|
||||
element.style.zIndex = "0";
|
||||
document.body.appendChild(element);
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
aria-hidden
|
||||
className="fixed inset-0 pointer-events-none"
|
||||
style={{
|
||||
zIndex: 0,
|
||||
...backgroundStyle,
|
||||
}}
|
||||
/>,
|
||||
document.body,
|
||||
);
|
||||
Object.assign(element.style, backgroundStyle as Record<string, string>);
|
||||
}, [backgroundStyle, isPattern]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -9,13 +9,22 @@ import {
|
||||
isPatternBackground,
|
||||
PATTERN_BACKGROUND_OPACITY,
|
||||
} from "@/lib/helpers/backgroundUtils";
|
||||
import {
|
||||
applyCachedThemeToDom,
|
||||
buildThemeCacheFromRestaurant,
|
||||
getThemeCache,
|
||||
removeCachedThemeBackground,
|
||||
setThemeCache,
|
||||
svgToDataUrl,
|
||||
type CachedRestaurantTheme,
|
||||
} from "@/lib/helpers/themeCache";
|
||||
import { useParams } from "next/navigation";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type CSSProperties,
|
||||
type ReactNode,
|
||||
@@ -37,32 +46,74 @@ export function PatternBackgroundProvider({ children }: { children: ReactNode })
|
||||
const { name: restaurantSlug } = useParams<{ name: string }>();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const restaurant = aboutData?.data;
|
||||
const [hydratedCache, setHydratedCache] = useState<CachedRestaurantTheme | null>(null);
|
||||
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 isPattern = restaurant
|
||||
? isPatternBackground(restaurant)
|
||||
: (hydratedCache?.isPattern ?? false);
|
||||
const menuColor =
|
||||
restaurant?.menuColor || hydratedCache?.menuColor || DEFAULT_MENU_COLOR;
|
||||
const baseTint = hexToRgba(menuColor, PATTERN_BACKGROUND_OPACITY);
|
||||
|
||||
useEffect(() => {
|
||||
const revokeBlobUrl = () => {
|
||||
if (blobUrlRef.current) {
|
||||
URL.revokeObjectURL(blobUrlRef.current);
|
||||
blobUrlRef.current = null;
|
||||
}
|
||||
setPatternImageUrl(null);
|
||||
};
|
||||
useLayoutEffect(() => {
|
||||
if (!restaurantSlug) return;
|
||||
|
||||
if (!isPattern || !restaurant?.bgUrl || !restaurantSlug) {
|
||||
const cached = getThemeCache(restaurantSlug);
|
||||
setHydratedCache(cached);
|
||||
|
||||
if (!cached) return;
|
||||
|
||||
applyCachedThemeToDom(cached);
|
||||
if (cached.patternDataUrl) {
|
||||
setPatternImageUrl(cached.patternDataUrl);
|
||||
}
|
||||
}, [restaurantSlug]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!restaurantSlug) {
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
removeCachedThemeBackground();
|
||||
setPatternImageUrl(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!restaurant) return;
|
||||
|
||||
const themeBase = buildThemeCacheFromRestaurant(restaurant);
|
||||
|
||||
if (!themeBase.isPattern || !themeBase.bgUrl) {
|
||||
clearPatternCssVariables();
|
||||
removeCachedThemeBackground();
|
||||
setPatternImageUrl(null);
|
||||
setThemeCache(restaurantSlug, {
|
||||
...themeBase,
|
||||
patternDataUrl: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
applyPatternCssVariables(menuColor);
|
||||
|
||||
const cached = getThemeCache(restaurantSlug);
|
||||
const cacheHit =
|
||||
cached?.isPattern &&
|
||||
cached.bgUrl === themeBase.bgUrl &&
|
||||
cached.menuColor === menuColor &&
|
||||
cached.patternDataUrl;
|
||||
|
||||
if (cacheHit) {
|
||||
setPatternImageUrl(cached.patternDataUrl!);
|
||||
setThemeCache(restaurantSlug, {
|
||||
...themeBase,
|
||||
patternDataUrl: cached.patternDataUrl,
|
||||
});
|
||||
applyCachedThemeToDom(cached);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
const proxyUrl = `/${restaurantSlug}/api/proxy-svg?url=${encodeURIComponent(restaurant.bgUrl)}`;
|
||||
const proxyUrl = `/${restaurantSlug}/api/proxy-svg?url=${encodeURIComponent(themeBase.bgUrl)}`;
|
||||
|
||||
fetch(proxyUrl)
|
||||
.then((response) => {
|
||||
@@ -74,26 +125,31 @@ export function PatternBackgroundProvider({ children }: { children: ReactNode })
|
||||
.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);
|
||||
const dataUrl = svgToDataUrl(colorizeSvg(svg, menuColor));
|
||||
setPatternImageUrl(dataUrl);
|
||||
|
||||
const nextCache = {
|
||||
...themeBase,
|
||||
patternDataUrl: dataUrl,
|
||||
};
|
||||
setThemeCache(restaurantSlug, nextCache);
|
||||
|
||||
const saved = getThemeCache(restaurantSlug);
|
||||
if (saved) {
|
||||
applyCachedThemeToDom(saved);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
revokeBlobUrl();
|
||||
if (!cancelled && cached?.patternDataUrl) {
|
||||
setPatternImageUrl(cached.patternDataUrl);
|
||||
applyCachedThemeToDom(cached);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearPatternCssVariables();
|
||||
revokeBlobUrl();
|
||||
};
|
||||
}, [isPattern, menuColor, restaurant?.bgUrl, restaurantSlug]);
|
||||
}, [menuColor, restaurant, restaurantSlug]);
|
||||
|
||||
const backgroundStyle = useMemo<CSSProperties>(
|
||||
() => ({
|
||||
|
||||
@@ -81,10 +81,10 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
{onPagerClick ? (
|
||||
<button
|
||||
onClick={onPagerClick}
|
||||
className="flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary dark:text-white dark:**:stroke-white"
|
||||
className="flex flex-col justify-arround items-center gap-[5px] text-disabled-text pointer-events-auto **:stroke-disabled-text"
|
||||
>
|
||||
<PagerIcon width={20} height={20} />
|
||||
<span className="text-xs2 dark:text-white">
|
||||
<span className="text-xs2">
|
||||
{t('Pager')}
|
||||
</span>
|
||||
</button>
|
||||
@@ -95,9 +95,7 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
href={`/${name}`}
|
||||
icon={
|
||||
<HomeIcon
|
||||
className={clsx(
|
||||
'transition-all duration-200 stroke-primary dark:stroke-black! dark:text-white'
|
||||
)}
|
||||
className="transition-all duration-200 stroke-primary"
|
||||
fill="white"
|
||||
stroke="currentColor"
|
||||
variant={isHomeRoute ? 'Bold' : 'Outline'}
|
||||
@@ -107,10 +105,13 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
<Link
|
||||
href={`/${name}/about`}
|
||||
className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white'
|
||||
'flex flex-col justify-arround items-center gap-[5px] pointer-events-auto min-w-0',
|
||||
isAboutRoute
|
||||
? 'text-primary **:stroke-primary'
|
||||
: 'text-disabled-text **:stroke-disabled-text',
|
||||
)}
|
||||
>
|
||||
<div className="shrink-0 text-primary dark:text-white">
|
||||
<div className="shrink-0">
|
||||
<Building
|
||||
key={`building-${buildingVariant}-${isAboutRoute}`}
|
||||
size={20}
|
||||
@@ -119,7 +120,7 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
|
||||
className='stroke-0'
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs2 text-center truncate w-full dark:text-white">
|
||||
<span className="text-xs2 text-center truncate w-full">
|
||||
{t('about')}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -18,16 +18,16 @@ function BottomNavLink({ icon, value, href, prefetch, ...restProps }: Props) {
|
||||
|
||||
return (
|
||||
<Link {...restProps} href={href} prefetch={shouldPrefetch} className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white',
|
||||
isActive && 'text-primary-foreground **:stroke-primary-foreground',
|
||||
'flex flex-col justify-arround items-center gap-[5px] pointer-events-auto min-w-0',
|
||||
isActive
|
||||
? 'text-primary **:stroke-primary'
|
||||
: 'text-disabled-text **:stroke-disabled-text',
|
||||
restProps.className ?? '',
|
||||
)}>
|
||||
<div className="shrink-0">
|
||||
{icon}
|
||||
</div>
|
||||
<span className={clsx(
|
||||
'text-xs2 text-center truncate w-full dark:text-white',
|
||||
)}>
|
||||
<span className="text-xs2 text-center truncate w-full">
|
||||
{value}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import type { LinkProps } from 'next/link'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import clsx from 'clsx'
|
||||
|
||||
type Props = {
|
||||
@@ -12,9 +11,6 @@ type Props = {
|
||||
} & LinkProps & React.AnchorHTMLAttributes<HTMLAnchorElement>
|
||||
|
||||
function BottomNavHighlightLink({ icon, value, href, ...restProps }: Props) {
|
||||
const pathname = usePathname();
|
||||
const isActive = pathname === href;
|
||||
|
||||
return (
|
||||
<Link {...restProps} href={href} className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto',
|
||||
@@ -25,7 +21,7 @@ function BottomNavHighlightLink({ icon, value, href, ...restProps }: Props) {
|
||||
)}>
|
||||
{icon}
|
||||
</div>
|
||||
<span className="text-xs2 dark:text-white">
|
||||
<span className="text-xs2 text-disabled-text">
|
||||
{value}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useLayoutEffect, useState } from 'react'
|
||||
import PingAnimation from './animations/PingAnimation';
|
||||
|
||||
type Props = {
|
||||
@@ -10,21 +10,23 @@ type Props = {
|
||||
} & React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
|
||||
|
||||
const LoadingOverlay = ({ visible = true, bgOpacity = 30, delay = 0, children = <PingAnimation /> }: Props) => {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [loaded, setLoaded] = useState(visible);
|
||||
|
||||
useEffect(() => {
|
||||
// Trigger fade-in after mount
|
||||
const timeout = setTimeout(() => setLoaded(visible), 300);
|
||||
return () => clearTimeout(timeout);
|
||||
useLayoutEffect(() => {
|
||||
setLoaded(visible);
|
||||
}, [visible]);
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
data-visible={visible}
|
||||
data-loaded={loaded}
|
||||
className={`absolute inset-0 flex items-center justify-center
|
||||
backdrop-blur-sm bg-background/${bgOpacity}
|
||||
opacity-0 transition-opacity duration-300 ease-in-out delay-${delay}
|
||||
transition-opacity duration-300 ease-in-out delay-${delay}
|
||||
data-[loaded=false]:-z-50
|
||||
data-[visible=true]:z-50
|
||||
data-[visible=true]:opacity-100`}
|
||||
@@ -34,4 +36,4 @@ const LoadingOverlay = ({ visible = true, bgOpacity = 30, delay = 0, children =
|
||||
)
|
||||
}
|
||||
|
||||
export default LoadingOverlay
|
||||
export default LoadingOverlay
|
||||
|
||||
@@ -55,7 +55,6 @@ export default function SplashScreen({
|
||||
};
|
||||
}, []);
|
||||
|
||||
const showLogoSpinner = Boolean(logo) && logoState === 'loading';
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -112,11 +111,7 @@ export default function SplashScreen({
|
||||
transition: 'opacity 0.3s',
|
||||
}}
|
||||
/>
|
||||
{showLogoSpinner && (
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="w-10 h-10 border-4 border-primary border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,20 +1,52 @@
|
||||
'use client';
|
||||
|
||||
import usePreference from '@/hooks/helpers/usePreference';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
|
||||
import SplashScreen from '@/components/overlays/SplashScreen';
|
||||
import { hexToOklch, calculateBrightness } from '@/lib/helpers/colorUtils';
|
||||
import {
|
||||
applyCachedThemeToDom,
|
||||
buildThemeCacheFromRestaurant,
|
||||
getCachedMenuColor,
|
||||
getThemeCache,
|
||||
setThemeCache,
|
||||
} from '@/lib/helpers/themeCache';
|
||||
|
||||
function getSplashStorageKey(restaurantSlug: string) {
|
||||
return `splash-seen:${restaurantSlug}`;
|
||||
}
|
||||
|
||||
function getSplashSessionKey(restaurantSlug: string) {
|
||||
return `splash-session:${restaurantSlug}`;
|
||||
}
|
||||
|
||||
function getSplashFingerprint(logo?: string | null, name?: string | null) {
|
||||
return `${logo ?? ''}|${name ?? ''}`;
|
||||
}
|
||||
|
||||
function readStoredRestaurantIdentity() {
|
||||
return {
|
||||
logo: localStorage.getItem('restaurant-logo'),
|
||||
name: localStorage.getItem('restaurant-name'),
|
||||
};
|
||||
}
|
||||
|
||||
function resolveSeenSplashFingerprint(restaurantSlug: string, currentFingerprint: string) {
|
||||
const storageKey = getSplashStorageKey(restaurantSlug);
|
||||
const seenFingerprint = localStorage.getItem(storageKey);
|
||||
|
||||
if (!seenFingerprint || seenFingerprint === '|') {
|
||||
if (currentFingerprint !== '|') {
|
||||
localStorage.setItem(storageKey, currentFingerprint);
|
||||
return currentFingerprint;
|
||||
}
|
||||
}
|
||||
|
||||
return seenFingerprint;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
@@ -43,69 +75,88 @@ function PreferenceWrapper({ children }: Props) {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [cachedLogo, setCachedLogo] = useState<string | null>(null);
|
||||
const [cachedName, setCachedName] = useState<string | null>(null);
|
||||
const splashCheckedRef = useRef(false);
|
||||
|
||||
const handleSplashDismiss = useCallback(() => {
|
||||
setShowSplash(false);
|
||||
|
||||
if (!restaurantSlug) return;
|
||||
|
||||
const logo = aboutData?.data?.logo || cachedLogo;
|
||||
const name = aboutData?.data?.name || cachedName;
|
||||
const stored = readStoredRestaurantIdentity();
|
||||
const logo = aboutData?.data?.logo || stored.logo || cachedLogo;
|
||||
const name = aboutData?.data?.name || stored.name || cachedName;
|
||||
const fingerprint = getSplashFingerprint(logo, name);
|
||||
|
||||
localStorage.setItem(getSplashStorageKey(restaurantSlug), fingerprint);
|
||||
sessionStorage.setItem(getSplashSessionKey(restaurantSlug), '1');
|
||||
}, [aboutData?.data?.logo, aboutData?.data?.name, cachedLogo, cachedName, restaurantSlug]);
|
||||
|
||||
useEffect(() => {
|
||||
if (splashCheckedRef.current) return;
|
||||
splashCheckedRef.current = true;
|
||||
|
||||
setMounted(true);
|
||||
|
||||
const savedColor = localStorage.getItem('theme-primary-color');
|
||||
if (savedColor) {
|
||||
const savedColor = getCachedMenuColor(restaurantSlug);
|
||||
const cachedTheme = restaurantSlug ? getThemeCache(restaurantSlug) : null;
|
||||
if (cachedTheme) {
|
||||
applyCachedThemeToDom(cachedTheme);
|
||||
} else if (savedColor) {
|
||||
applyPrimaryColor(savedColor);
|
||||
}
|
||||
|
||||
const savedLogo = localStorage.getItem('restaurant-logo');
|
||||
const savedName = localStorage.getItem('restaurant-name');
|
||||
const { logo: savedLogo, name: savedName } = readStoredRestaurantIdentity();
|
||||
if (savedLogo) setCachedLogo(savedLogo);
|
||||
if (savedName) setCachedName(savedName);
|
||||
|
||||
if (!restaurantSlug) return;
|
||||
|
||||
if (sessionStorage.getItem(getSplashSessionKey(restaurantSlug))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentFingerprint = getSplashFingerprint(savedLogo, savedName);
|
||||
const seenFingerprint = localStorage.getItem(getSplashStorageKey(restaurantSlug));
|
||||
const seenFingerprint = resolveSeenSplashFingerprint(restaurantSlug, currentFingerprint);
|
||||
|
||||
if (seenFingerprint !== currentFingerprint) {
|
||||
setShowSplash(true);
|
||||
sessionStorage.setItem(getSplashSessionKey(restaurantSlug), '1');
|
||||
}
|
||||
}, [restaurantSlug]);
|
||||
|
||||
useEffect(() => {
|
||||
if (aboutData?.data?.menuColor) {
|
||||
localStorage.setItem('theme-primary-color', aboutData.data.menuColor);
|
||||
const menuColor = aboutData?.data?.menuColor;
|
||||
if (!menuColor || !restaurantSlug) return;
|
||||
|
||||
if (aboutData.data.logo) {
|
||||
localStorage.setItem('restaurant-logo', aboutData.data.logo);
|
||||
}
|
||||
if (aboutData.data.name) {
|
||||
localStorage.setItem('restaurant-name', aboutData.data.name);
|
||||
}
|
||||
const restaurant = aboutData.data;
|
||||
const cached = getThemeCache(restaurantSlug);
|
||||
|
||||
applyPrimaryColor(aboutData.data.menuColor);
|
||||
setThemeCache(restaurantSlug, {
|
||||
menuColor,
|
||||
bgUrl: restaurant.bgUrl,
|
||||
isPattern: buildThemeCacheFromRestaurant(restaurant).isPattern,
|
||||
patternDataUrl: cached?.patternDataUrl ?? null,
|
||||
});
|
||||
|
||||
if (restaurant.logo) {
|
||||
localStorage.setItem('restaurant-logo', restaurant.logo);
|
||||
}
|
||||
if (restaurant.name) {
|
||||
localStorage.setItem('restaurant-name', restaurant.name);
|
||||
}
|
||||
|
||||
applyPrimaryColor(menuColor);
|
||||
|
||||
const currentFingerprint = getSplashFingerprint(
|
||||
restaurant.logo ?? readStoredRestaurantIdentity().logo,
|
||||
restaurant.name ?? readStoredRestaurantIdentity().name,
|
||||
);
|
||||
const seenFingerprint = localStorage.getItem(getSplashStorageKey(restaurantSlug));
|
||||
if (seenFingerprint === '|' && currentFingerprint !== '|') {
|
||||
localStorage.setItem(getSplashStorageKey(restaurantSlug), currentFingerprint);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [aboutData?.data?.menuColor]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!restaurantSlug || showSplash) return;
|
||||
|
||||
const logo = aboutData?.data?.logo || cachedLogo;
|
||||
const name = aboutData?.data?.name || cachedName;
|
||||
const fingerprint = getSplashFingerprint(logo, name);
|
||||
const seenFingerprint = localStorage.getItem(getSplashStorageKey(restaurantSlug));
|
||||
|
||||
if (seenFingerprint === '|' && fingerprint !== '|') {
|
||||
localStorage.setItem(getSplashStorageKey(restaurantSlug), fingerprint);
|
||||
}
|
||||
}, [aboutData?.data?.logo, aboutData?.data?.name, cachedLogo, cachedName, restaurantSlug, showSplash]);
|
||||
}, [aboutData?.data?.menuColor, restaurantSlug]);
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute('data-theme', nightMode ? 'dark' : 'light');
|
||||
|
||||
Reference in New Issue
Block a user