This commit is contained in:
ct
2025-07-07 21:17:00 +08:00
parent 23fa3aec04
commit 6a66f96d22
31 changed files with 227 additions and 232 deletions

View File

@@ -174,7 +174,7 @@ const Editor = () => {
return (
<>
<div className="relative mx-auto flex min-h-[98vh] flex-col space-y-2 pt-4" style={{ width: `${responsiveWidth}px` }}>
<div className="relative mx-auto flex min-h-[93vh] flex-col space-y-2 pt-4" style={{ width: `${responsiveWidth}px` }}>
<EditSidebar isOpen={isEditSidebarOpen} onClose={handleEditClose} />
<EditNavSidebar isOpen={isEditNavSidebarOpen} onClose={handleEditNavClose} />
<TextSidebar isOpen={isTextSidebarOpen} onClose={handleTextSidebarClose} />
@@ -192,7 +192,7 @@ const Editor = () => {
<div className="space-y-3">
<div>
<div className="relative mb-3 flex justify-center">
<img width="180" height="180" src="https://cdn.memeaigen.com/landing/dancing-potato.gif"></img>
<img width="180" height="180" src="https://cdn.memefa.st/landing/dancing-potato.gif"></img>
</div>
<div className="w-full space-y-2 text-center">

View File

@@ -41,7 +41,7 @@ const FONTS = {
weights: [400],
styles: ['normal'],
description: 'Decorative display font',
preview: 'MEMEAIGEN.COM',
preview: 'memefa.st',
},
arial: {
name: 'Arial',

View File

@@ -2,9 +2,9 @@ const sampleTimelineElements = [
{
id: '1',
type: 'video',
source_webm: 'https://cdn.memeaigen.com/g1/webm/they-not-like-us-oiia-cat-version.webm',
source_mov: 'https://cdn.memeaigen.com/g1/mov/they-not-like-us-oiia-cat-version.mov',
poster: 'https://cdn.memeaigen.com/g1/webp/they-not-like-us-oiia-cat-version.webp',
source_webm: 'https://cdn.memefa.st/g1/webm/they-not-like-us-oiia-cat-version.webm',
source_mov: 'https://cdn.memefa.st/g1/mov/they-not-like-us-oiia-cat-version.mov',
poster: 'https://cdn.memefa.st/g1/webp/they-not-like-us-oiia-cat-version.webp',
name: 'They not like us cat',
startTime: 0,
layer: 0,
@@ -19,9 +19,9 @@ const sampleTimelineElements = [
{
id: '2',
type: 'video',
source_webm: 'https://cdn.memeaigen.com/g1/webm/sad-cat.webm',
source_mov: 'https://cdn.memeaigen.com/g1/mov/sad-cat.mov',
poster: 'https://cdn.memeaigen.com/g1/webp/sad-cat.webp',
source_webm: 'https://cdn.memefa.st/g1/webm/sad-cat.webm',
source_mov: 'https://cdn.memefa.st/g1/mov/sad-cat.mov',
poster: 'https://cdn.memefa.st/g1/webp/sad-cat.webp',
name: 'Sad cat meme',
startTime: 6,
layer: 0,
@@ -36,9 +36,9 @@ const sampleTimelineElements = [
{
id: '3',
type: 'video',
source_webm: 'https://cdn.memeaigen.com/g1/webm/este-cat-dance.webm',
source_mov: 'https://cdn.memeaigen.com/g1/mov/este-cat-dance.mov',
poster: 'https://cdn.memeaigen.com/g1/webp/este-cat-dance.webp',
source_webm: 'https://cdn.memefa.st/g1/webm/este-cat-dance.webm',
source_mov: 'https://cdn.memefa.st/g1/mov/este-cat-dance.mov',
poster: 'https://cdn.memefa.st/g1/webp/este-cat-dance.webp',
name: 'Este cat dance',
startTime: 2,
layer: 1,
@@ -95,7 +95,7 @@ const sampleTimelineElements = [
{
id: '6',
type: 'image',
source: 'https://cdn.memeaigen.com/g1/webp/este-cat-dance.webp',
source: 'https://cdn.memefa.st/g1/webp/este-cat-dance.webp',
name: 'Este cat dance',
startTime: 0,
layer: 5,

View File

@@ -213,7 +213,7 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration, watermark
stage.add(layer);
const watermarkText = new Konva.Text({
text: 'MEMEAIGEN.COM',
text: 'memefa.st',
x: dimensions.width / 2,
y: dimensions.height / 2 + dimensions.height * 0.2,
fontSize: WATERMARK_CONFIG.fontSize,
@@ -692,7 +692,7 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration, watermark
const blob = new Blob([data.buffer], { type: 'video/mp4' });
const epochTimestamp = Date.now();
const fileName = `memeaigen-${epochTimestamp}.mp4`;
const fileName = `memefast-${epochTimestamp}.mp4`;
// Store the blob and filename in state instead of auto-downloading
setVideoBlob(blob);

View File

@@ -277,8 +277,9 @@ const VideoPreview = ({
}}
>
<Button
variant="secondary"
id="open-text-editor"
className="h-16 w-16 rounded-full border shadow-sm"
className="h-16 w-16 rounded-full shadow-xl"
onClick={() => {
handleElementSelect(element.id);
onOpenTextSidebar();
@@ -330,7 +331,7 @@ const VideoPreview = ({
{watermarked && (
<Text
key={`watermark-${fontsLoaded}`}
text="MEMEAIGEN.COM"
text="memefa.st"
x={dimensions.width / 2}
y={dimensions.height / 2 + dimensions.height * 0.2}
fontSize={WATERMARK_CONFIG.fontSize}

View File

@@ -26,7 +26,7 @@ export default function EditNavSidebar({ isOpen, onClose }) {
<SheetContent side="left" className="w-[220px] overflow-y-auto">
<SheetHeader>
<SheetTitle className="flex items-center gap-3">
<div className="font-display ml-0 text-lg tracking-wide md:ml-3 md:text-xl">MEMEAIGEN</div>
<div className="font-display ml-0 text-lg tracking-wide md:ml-3 md:text-xl">MEMEFAST</div>
</SheetTitle>
</SheetHeader>

View File

@@ -1,9 +1,6 @@
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { useMitt } from '@/plugins/MittContext';
import CartIcon from '@/reusables/cart-icon';
import useLocalSettingsStore from '@/stores/localSettingsStore';
import { Menu } from 'lucide-react';
const EditorHeader = ({ className = '', onNavClick = () => {}, isNavActive = false }) => {
const { getSetting } = useLocalSettingsStore();
@@ -15,28 +12,33 @@ const EditorHeader = ({ className = '', onNavClick = () => {}, isNavActive = fal
};
return (
<div className={cn('flex w-full items-center justify-between rounded-xl bg-white p-2 shadow-sm dark:bg-neutral-800', className)}>
<Button onClick={onNavClick} variant="outline" size="icon" className="invisible rounded">
<Menu className="h-8 w-8" />
</Button>
<div className={cn('flex w-full items-center justify-center', className)}>
<h1 className="font-display ml-0 text-lg tracking-wide md:ml-3 md:text-xl">
<span className="text-foreground">MEME</span>
<span className="text-muted-foreground">AI</span>
<span className="text-foreground">GEN</span>
<span className="text-muted-foreground">FAST</span>
</h1>
<Button
variant="outline"
className="invisible inline-flex gap-1 rounded"
onClick={() => {
openUpgradeSheet();
}}
>
{/* <span className="text-sm font-semibold">0</span> */}
<CartIcon className="h-8 w-8" />
</Button>
</div>
// <div className={cn('flex w-full items-center justify-between rounded-xl bg-white p-2 shadow-sm dark:bg-neutral-800', className)}>
// <Button onClick={onNavClick} variant="outline" size="icon" className="invisible rounded">
// <Menu className="h-8 w-8" />
// </Button>
// <h1 className="font-display ml-0 text-lg tracking-wide md:ml-3 md:text-xl">
// <span className="text-foreground">MEME</span>
// <span className="text-muted-foreground">FAST</span>
// </h1>
// <Button
// variant="outline"
// className="invisible inline-flex gap-1 rounded"
// onClick={() => {
// openUpgradeSheet();
// }}
// >
// {/* <span className="text-sm font-semibold">0</span> */}
// <CartIcon className="h-8 w-8" />
// </Button>
// </div>
);
};

View File

@@ -11,7 +11,7 @@
{
"id": "background",
"type": "image",
"source": "https://cdn.memeaigen.com/system-i/si_1749805418324-out-0.webp",
"source": "https://cdn.memefa.st/system-i/si_1749805418324-out-0.webp",
"name": "Este cat dance",
"startTime": 0,
"layer": 1,
@@ -28,9 +28,9 @@
{
"id": "meme",
"type": "video",
"source_webm": "https://cdn.memeaigen.com/g1/webm/este-cat-dance.webm",
"source_mov": "https://cdn.memeaigen.com/g1/mov/este-cat-dance.mov",
"poster": "https://cdn.memeaigen.com/g1/webp/este-cat-dance.webp",
"source_webm": "https://cdn.memefa.st/g1/webm/este-cat-dance.webm",
"source_mov": "https://cdn.memefa.st/g1/mov/este-cat-dance.mov",
"poster": "https://cdn.memefa.st/g1/webp/este-cat-dance.webp",
"name": "Este cat dance",
"startTime": 0,
"layer": 2,

View File

@@ -3,7 +3,7 @@ export default function ComingSoon() {
<div className="flex min-h-screen flex-col items-center justify-center bg-white px-4 text-center dark:bg-black">
<div className="max-w-2xl space-y-5">
<div className="grid items-center justify-center space-y-3">
<h1 className="font-display ml-0 text-2xl tracking-wide md:ml-3 md:text-4xl">MEMEAIGEN</h1>
<h1 className="font-display ml-0 text-2xl tracking-wide md:ml-3 md:text-4xl">MEMEFAST</h1>
<div className="space-y-1" data-nosnippet="true">
<div className="inline-block rounded-full bg-neutral-100 px-3 py-1 text-sm font-medium text-neutral-700">Coming Soon</div>
@@ -13,7 +13,7 @@ export default function ComingSoon() {
<div className="space-y-3">
<h2 className="mx-auto max-w-lg text-neutral-500 md:text-2xl">Make video memes with AI</h2>
<p className="font-medium text-neutral-600">memeaigen.com</p>
<p className="font-medium text-neutral-600">memefa.st</p>
</div>
</div>

View File

@@ -15,10 +15,6 @@ const FAQDiscord = () => {
q: 'Why is video export slow for me?',
a: 'Video processing happens entirely in your browser using advanced web technology. Export speed depends on your video content complexity and device performance. High-end devices export quickly, while older/slower devices may take longer or even crash. If your phone is too slow, try using a faster device like a desktop computer for better performance.',
},
{
q: 'What AI features are coming?',
a: "Soon you'll be able to generate custom captions and backgrounds using AI. Enter any text prompt and get tailored content!",
},
{
q: 'What video format do you export?',
a: 'We export high-quality MP4 videos optimized for all social media platforms in 9:16 format, which is compatible for TikTok, Youtube Shorts, Instagram Reels, and more.',
@@ -31,6 +27,10 @@ const FAQDiscord = () => {
q: 'How often do you add new content?',
a: 'We just started building this platform and will gradually add more meme templates and backgrounds over time, so everyone can continue using it for free with fresh content! Want a certain content? Let us know in our Discord group.',
},
{
q: 'I have more questions!',
a: 'Great! Join our Discord group and ask away!',
},
];
return (
@@ -41,7 +41,10 @@ const FAQDiscord = () => {
</div>
<div className="grid gap-6 md:flex">
<div id="faq" className="bg-background max-w-4xl flex-3/5 rounded-2xl border p-6 sm:p-8">
<div
id="faq"
className="max-w-4xl flex-3/5 rounded-2xl border bg-gradient-to-br from-transparent to-purple-500/5 p-6 sm:p-8 dark:to-purple-300/10"
>
<Accordion type="single" collapsible className="w-full" defaultValue="item-1">
{faqData.map((faq, index) => (
<AccordionItem key={index} value={`item-${index + 1}`} className="border-b last:border-b-0">
@@ -63,10 +66,10 @@ const FAQDiscord = () => {
</svg>
</div>
<div className="text-left">
<h3 className="text-foreground text-2xl font-bold">MEMEAIGEN Discord</h3>
<h3 className="text-foreground text-2xl font-bold">MEMEFAST Discord</h3>
<p className="text-muted-foreground text-sm leading-relaxed text-wrap">
Join our Discord community to connect with other creators, get help, stay up to date and help shape the future of
MEMEAIGEN.
MEMEFAST.
</p>
</div>
</div>

View File

@@ -1,54 +1,53 @@
import { Bot, Download, Heart, Library, Smartphone, Video } from 'lucide-react';
import { Download, Heart, Library, Smartphone, Video } from 'lucide-react';
const Features = () => {
const features = [
{
icon: Heart,
title: 'Make video memes for free',
description: 'Access 200+ meme and background libraries without paying a cent!',
},
{
icon: Video,
title: 'Web-powered Video Editor',
description: 'Easy video editor with editable text, background, memes, built into the web. No additional software required.',
gradient: 'bg-gradient-to-br from-transparent to-blue-500/5 dark:to-blue-400/10 hover:bg-gradient-to-tl',
},
{
icon: Heart,
title: 'Built-in over 200+ memes, for now',
description: 'Access meme and background with our editor without paying a cent.',
gradient: 'bg-gradient-to-br from-transparent to-pink-500/5 dark:to-pink-400/10 hover:bg-gradient-to-tl',
},
{
icon: Download,
title: 'Export in minutes',
description: 'Download high-quality 720p MP4 videos optimized for TikTok, Youtube Shorts, Instagram Reels, and more.',
gradient: 'bg-gradient-to-br from-transparent to-green-500/5 dark:to-green-400/10 hover:bg-gradient-to-tl',
},
{
icon: Smartphone,
title: 'Works Everywhere',
description: 'Create on desktop, tablet, or mobile! Potato devices not recommended though.',
gradient: 'bg-gradient-to-br from-transparent to-purple-500/5 dark:to-purple-400/10 hover:bg-gradient-to-tl',
},
{
icon: Library,
title: 'Meme Library Updates',
description: 'Soon we will be adding more memes and backgrounds to the library!',
comingSoon: true,
},
{
icon: Bot,
title: 'AI Caption & Backgrounds',
description: 'Smart caption and background generation coming soon.',
comingSoon: true,
gradient: 'bg-gradient-to-br from-transparent to-orange-500/5 dark:to-orange-400/10 hover:bg-gradient-to-tl',
},
];
return (
<section className="">
<div className="mx-auto max-w-6xl space-y-10 px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 lg:gap-4">
<div className="flex flex-wrap justify-center gap-3 md:grid-cols-2 lg:grid-cols-3 lg:gap-4">
{features.map((feature, index) => (
<div
key={index}
className="group bg-card hover:bg-muted/50 relative rounded-2xl border p-6 transition-all duration-300 lg:p-8"
className={`group hover:bg-muted/50 relative h-auto min-h-[275px] w-[275px] rounded-2xl border p-6 shadow-lg ${feature.gradient} transition-all duration-300 lg:p-8`}
>
{feature.comingSoon && (
<div className="bg-foreground text-background absolute -top-2 -right-2 rounded-full px-2 py-1 text-xs font-medium uppercase">
Coming Soon
<div className="bg-foreground text-background absolute -top-2 -right-2 rounded-full px-2 py-1 text-xs font-medium">
Coming Soon!
</div>
)}

View File

@@ -2,11 +2,11 @@ const Footer = () => {
const currentYear = new Date().getFullYear();
return (
<section className="">
<section className="pt-10">
<div className="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
<div className="border-t pt-8">
<div className="flex flex-col items-center justify-between space-y-4 sm:flex-row sm:space-y-0">
<div className="text-muted-foreground text-sm">© {currentYear} MEMEAIGEN. All rights reserved.</div>
<div className="text-muted-foreground text-sm">© {currentYear} MEMEFAST. All rights reserved.</div>
<div className="flex space-x-6">
<a href="/" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Home

View File

@@ -1,5 +1,4 @@
import CountUp from '@/components/reactbits/CountUp/CountUp';
import ShinyText from '@/components/reactbits/ShinyText/ShinyText';
const Hero = () => {
return (
@@ -16,17 +15,11 @@ const Hero = () => {
<div className="space-y-0">
<h1 className="font-display text-6xl font-black tracking-tight sm:text-7xl lg:text-8xl">
<span className="text-foreground">MEME</span>
<span className="text-muted-foreground">AI</span>
<span className="text-foreground">GEN</span>
<span className="text-muted-foreground">FAST</span>
</h1>
<h2 className="">
<ShinyText
text="Create viral memes in seconds for free"
disabled={false}
speed={3}
className="text-muted-foreground mx-auto max-w-4xl text-xl leading-relaxed font-light sm:text-2xl lg:text-3xl"
/>
<h2 className="text-muted-foreground mx-auto max-w-4xl text-xl leading-relaxed font-light sm:text-2xl lg:text-3xl">
Simple, fast, and free meme video editor
</h2>
</div>

File diff suppressed because one or more lines are too long