This commit is contained in:
ct
2025-07-17 04:58:07 +08:00
parent ec89417b23
commit 0892f252a4
3 changed files with 89 additions and 16 deletions

View File

@@ -0,0 +1,85 @@
import { useLayoutEffect, useState } from 'react';
import { Skeleton } from '@/components/ui/skeleton';
import { LAYOUT_CONSTANTS, calculateOptimalMaxWidth, calculateResponsiveWidth, calculateResponsiveScale } from '@/modules/editor/utils/layout-constants';
// Hook for responsive dimensions (same as Editor)
const useResponsiveDimensions = () => {
const [dimensions, setDimensions] = useState(() => ({
maxWidth: calculateOptimalMaxWidth(),
responsiveWidth: calculateResponsiveWidth(),
}));
useLayoutEffect(() => {
const newMaxWidth = calculateOptimalMaxWidth();
const newResponsiveWidth = calculateResponsiveWidth();
setDimensions({
maxWidth: newMaxWidth,
responsiveWidth: newResponsiveWidth,
});
}, []);
return dimensions;
};
// Hook for responsive canvas scale (same as EditorCanvas)
const useResponsiveCanvas = (maxWidth = 350) => {
const [scale, setScale] = useState(() => calculateResponsiveScale(maxWidth));
useLayoutEffect(() => {
setScale(calculateResponsiveScale(maxWidth));
}, [maxWidth]);
return scale;
};
const EditorSkeleton = () => {
const { maxWidth, responsiveWidth } = useResponsiveDimensions();
const scale = useResponsiveCanvas(maxWidth);
const displayWidth = LAYOUT_CONSTANTS.CANVAS_WIDTH * scale;
const displayHeight = LAYOUT_CONSTANTS.CANVAS_HEIGHT * scale;
return (
<div className="relative mx-auto flex min-h-[88vh] flex-col space-y-2" style={{ width: `${responsiveWidth}px` }}>
{/* Header Skeleton - EditorHeader currently returns empty <></> */}
<div className="mx-auto" style={{ width: `${responsiveWidth}px` }}>
{/* Header is empty in actual component, so we skip it */}
</div>
{/* Canvas Skeleton - matching EditorCanvas structure */}
<div className="flex w-full justify-center">
<div
style={{
width: `${displayWidth}px`,
height: `${displayHeight}px`,
}}
>
<Skeleton
className="origin-top-left rounded-3xl border bg-white shadow-sm dark:bg-black bg-gradient-to-r from-muted via-background to-muted bg-[length:200%_100%] animate-shimmer"
style={{
width: `${LAYOUT_CONSTANTS.CANVAS_WIDTH}px`,
height: `${LAYOUT_CONSTANTS.CANVAS_HEIGHT}px`,
transform: `scale(${scale})`,
}}
/>
</div>
</div>
{/* Controls Skeleton - matching EditorControls structure */}
<div className="mx-auto flex items-center justify-center gap-2" style={{ width: `${responsiveWidth}px` }}>
{/* Play/Pause button */}
<Skeleton className="h-12 w-12 rounded-full border shadow-sm bg-gradient-to-r from-muted via-background to-muted bg-[length:200%_100%] animate-shimmer" />
{/* Edit button */}
<Skeleton className="h-12 w-12 rounded-full border shadow-sm bg-gradient-to-r from-muted via-background to-muted bg-[length:200%_100%] animate-shimmer" />
{/* Refresh button */}
<Skeleton className="h-12 w-12 rounded-full border shadow-sm bg-gradient-to-r from-muted via-background to-muted bg-[length:200%_100%] animate-shimmer" />
{/* Download button */}
<Skeleton className="h-12 w-12 rounded-full border shadow-sm bg-gradient-to-r from-muted via-background to-muted bg-[length:200%_100%] animate-shimmer" />
</div>
</div>
);
};
export default EditorSkeleton;

View File

@@ -1,3 +1,4 @@
import EditorSkeleton from '@/components/editor/EditorSkeleton.jsx';
import { useEffect, useState } from 'react';
import BrandLogo from './partials/BrandLogo.jsx';
import FAQDiscord from './partials/FAQDiscord.jsx';
@@ -24,13 +25,7 @@ const Home = ({ faqData, popularKeywords }) => {
<div className="min-h-[100vh] space-y-0 bg-neutral-50 py-6 dark:bg-black">
<BrandLogo className="pb-2" />
<div className="to-muted/10 w-full bg-gradient-to-b from-transparent dark:from-transparent dark:to-neutral-900">
{isClient && Editor ? (
<Editor />
) : (
<div className="flex h-96 items-center justify-center">
<div className="text-muted-foreground">Loading editor...</div>
</div>
)}
{isClient && Editor ? <Editor /> : <EditorSkeleton />}
</div>
<div className="space-y-16">
<Hero />

View File

@@ -1,9 +1,9 @@
import { MemeCard } from '@/components/custom/meme-card';
import EditorSkeleton from '@/components/editor/EditorSkeleton';
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@/components/ui/breadcrumb';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { KeywordBadge } from '@/components/ui/keyword-badge';
import { Spinner } from '@/components/ui/spinner';
import Footer from '@/pages/home/partials/Footer';
import { Link } from '@inertiajs/react';
import { ArrowLeft } from 'lucide-react';
@@ -94,14 +94,7 @@ export default function MemeShow({ meme, relatedMemes }: Props) {
setInitialText={(setText) => setText('add your meme caption here')}
/>
) : (
<div className="flex h-96 items-center justify-center text-center">
<div className="space-y-2">
<Spinner />
<div className="text-muted-foreground" data-nosnippet>
Loading meme video editor...
</div>
</div>
</div>
<EditorSkeleton />
)}
</div>
<div className="container mx-auto grid justify-center gap-5 lg:grid-cols-1" id="more-info">