This commit is contained in:
ct
2025-07-15 00:43:37 +08:00
parent e7c6c02785
commit 8bb6705031
9 changed files with 481 additions and 58 deletions

View File

@@ -24033,6 +24033,317 @@ public static function getContainer()
}
}
namespace Maatwebsite\Excel\Facades {
/**
*
*
*/
class Excel {
/**
*
*
* @param object $export
* @param string|null $fileName
* @param string $writerType
* @param array $headers
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @static
*/
public static function download($export, $fileName, $writerType = null, $headers = [])
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->download($export, $fileName, $writerType, $headers);
}
/**
*
*
* @param string|null $disk Fallback for usage with named properties
* @param object $export
* @param string $filePath
* @param string|null $diskName
* @param string $writerType
* @param mixed $diskOptions
* @return bool
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @static
*/
public static function store($export, $filePath, $diskName = null, $writerType = null, $diskOptions = [], $disk = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->store($export, $filePath, $diskName, $writerType, $diskOptions, $disk);
}
/**
*
*
* @param object $export
* @param string $filePath
* @param string|null $disk
* @param string $writerType
* @param mixed $diskOptions
* @return \Illuminate\Foundation\Bus\PendingDispatch
* @static
*/
public static function queue($export, $filePath, $disk = null, $writerType = null, $diskOptions = [])
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->queue($export, $filePath, $disk, $writerType, $diskOptions);
}
/**
*
*
* @param object $export
* @param string $writerType
* @return string
* @static
*/
public static function raw($export, $writerType)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->raw($export, $writerType);
}
/**
*
*
* @param object $import
* @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath
* @param string|null $disk
* @param string|null $readerType
* @return \Maatwebsite\Excel\Reader|\Illuminate\Foundation\Bus\PendingDispatch
* @static
*/
public static function import($import, $filePath, $disk = null, $readerType = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->import($import, $filePath, $disk, $readerType);
}
/**
*
*
* @param object $import
* @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath
* @param string|null $disk
* @param string|null $readerType
* @return array
* @static
*/
public static function toArray($import, $filePath, $disk = null, $readerType = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->toArray($import, $filePath, $disk, $readerType);
}
/**
*
*
* @param object $import
* @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath
* @param string|null $disk
* @param string|null $readerType
* @return \Illuminate\Support\Collection
* @static
*/
public static function toCollection($import, $filePath, $disk = null, $readerType = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->toCollection($import, $filePath, $disk, $readerType);
}
/**
*
*
* @param \Illuminate\Contracts\Queue\ShouldQueue $import
* @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $filePath
* @param string|null $disk
* @param string $readerType
* @return \Illuminate\Foundation\Bus\PendingDispatch
* @static
*/
public static function queueImport($import, $filePath, $disk = null, $readerType = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->queueImport($import, $filePath, $disk, $readerType);
}
/**
* Register a custom macro.
*
* @param string $name
* @param object|callable $macro
* @param-closure-this static $macro
* @return void
* @static
*/
public static function macro($name, $macro)
{
\Maatwebsite\Excel\Excel::macro($name, $macro);
}
/**
* Mix another object into the class.
*
* @param object $mixin
* @param bool $replace
* @return void
* @throws \ReflectionException
* @static
*/
public static function mixin($mixin, $replace = true)
{
\Maatwebsite\Excel\Excel::mixin($mixin, $replace);
}
/**
* Checks if macro is registered.
*
* @param string $name
* @return bool
* @static
*/
public static function hasMacro($name)
{
return \Maatwebsite\Excel\Excel::hasMacro($name);
}
/**
* Flush the existing macros.
*
* @return void
* @static
*/
public static function flushMacros()
{
\Maatwebsite\Excel\Excel::flushMacros();
}
/**
*
*
* @param string $concern
* @param callable $handler
* @param string $event
* @static
*/
public static function extend($concern, $handler, $event = 'Maatwebsite\\Excel\\Events\\BeforeWriting')
{
return \Maatwebsite\Excel\Excel::extend($concern, $handler, $event);
}
/**
* When asserting downloaded, stored, queued or imported, use regular expression
* to look for a matching file path.
*
* @return void
* @static
*/
public static function matchByRegex()
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
$instance->matchByRegex();
}
/**
* When asserting downloaded, stored, queued or imported, use regular string
* comparison for matching file path.
*
* @return void
* @static
*/
public static function doNotMatchByRegex()
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
$instance->doNotMatchByRegex();
}
/**
*
*
* @param string $fileName
* @param callable|null $callback
* @static
*/
public static function assertDownloaded($fileName, $callback = null)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertDownloaded($fileName, $callback);
}
/**
*
*
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
* @static
*/
public static function assertStored($filePath, $disk = null, $callback = null)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertStored($filePath, $disk, $callback);
}
/**
*
*
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
* @static
*/
public static function assertQueued($filePath, $disk = null, $callback = null)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertQueued($filePath, $disk, $callback);
}
/**
*
*
* @static
*/
public static function assertQueuedWithChain($chain)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertQueuedWithChain($chain);
}
/**
*
*
* @param string $classname
* @param callable|null $callback
* @static
*/
public static function assertExportedInRaw($classname, $callback = null)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertExportedInRaw($classname, $callback);
}
/**
*
*
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
* @static
*/
public static function assertImported($filePath, $disk = null, $callback = null)
{
/** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
return $instance->assertImported($filePath, $disk, $callback);
}
}
}
namespace ProtoneMedia\LaravelFFMpeg\Support {
/**
*
@@ -24332,6 +24643,49 @@ public static function getConfig()
}
}
namespace Illuminate\Support {
/**
*
*
* @template TKey of array-key
* @template-covariant TValue
* @implements \ArrayAccess<TKey, TValue>
* @implements \Illuminate\Support\Enumerable<TKey, TValue>
*/
class Collection {
/**
*
*
* @see \Maatwebsite\Excel\Mixins\DownloadCollectionMixin::downloadExcel()
* @param string $fileName
* @param string|null $writerType
* @param mixed $withHeadings
* @param array $responseHeaders
* @static
*/
public static function downloadExcel($fileName, $writerType = null, $withHeadings = false, $responseHeaders = [])
{
return \Illuminate\Support\Collection::downloadExcel($fileName, $writerType, $withHeadings, $responseHeaders);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\StoreCollectionMixin::storeExcel()
* @param string $filePath
* @param string|null $disk
* @param string|null $writerType
* @param mixed $withHeadings
* @static
*/
public static function storeExcel($filePath, $disk = null, $writerType = null, $withHeadings = false)
{
return \Illuminate\Support\Collection::storeExcel($filePath, $disk, $writerType, $withHeadings);
}
}
}
namespace Illuminate\Http {
/**
*
@@ -26881,6 +27235,64 @@ public static function mergeConstraintsFrom($from)
return $instance->mergeConstraintsFrom($from);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\DownloadQueryMacro::__invoke()
* @param string $fileName
* @param string|null $writerType
* @param mixed $withHeadings
* @static
*/
public static function downloadExcel($fileName, $writerType = null, $withHeadings = false)
{
return \Illuminate\Database\Eloquent\Builder::downloadExcel($fileName, $writerType, $withHeadings);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\StoreQueryMacro::__invoke()
* @param string $filePath
* @param string|null $disk
* @param string|null $writerType
* @param mixed $withHeadings
* @static
*/
public static function storeExcel($filePath, $disk = null, $writerType = null, $withHeadings = false)
{
return \Illuminate\Database\Eloquent\Builder::storeExcel($filePath, $disk, $writerType, $withHeadings);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\ImportMacro::__invoke()
* @param string $filename
* @param string|null $disk
* @param string|null $readerType
* @static
*/
public static function import($filename, $disk = null, $readerType = null)
{
return \Illuminate\Database\Eloquent\Builder::import($filename, $disk, $readerType);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\ImportAsMacro::__invoke()
* @param string $filename
* @param callable $mapping
* @param string|null $disk
* @param string|null $readerType
* @static
*/
public static function importAs($filename, $mapping, $disk = null, $readerType = null)
{
return \Illuminate\Database\Eloquent\Builder::importAs($filename, $mapping, $disk, $readerType);
}
/**
* Set the columns to be selected.
*
@@ -29666,6 +30078,7 @@ class Twitter extends \Artesaos\SEOTools\Facades\TwitterCard {}
class OpenGraph extends \Artesaos\SEOTools\Facades\OpenGraph {}
class Horizon extends \Laravel\Horizon\Horizon {}
class Socialite extends \Laravel\Socialite\Facades\Socialite {}
class Excel extends \Maatwebsite\Excel\Facades\Excel {}
class FFMpeg extends \ProtoneMedia\LaravelFFMpeg\Support\FFMpeg {}
class ResponseCache extends \Spatie\ResponseCache\Facades\ResponseCache {}
class Hashids extends \Vinkla\Hashids\Facades\Hashids {}

BIN
database/.DS_Store vendored

Binary file not shown.

View File

@@ -2,8 +2,8 @@
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{

Binary file not shown.

View File

@@ -65,8 +65,9 @@ public function run(): void
// Skip empty or malformed records
if (empty($meme_record['filename']) || empty($meme_record['type']) || empty($meme_record['name'])) {
$this->command->warn("⏭️ Skipping malformed CSV record at line " . ($index + 1) . ": missing filename, type, or name");
$this->command->warn('⏭️ Skipping malformed CSV record at line '.($index + 1).': missing filename, type, or name');
$total_skipped++;
continue;
}
@@ -93,12 +94,12 @@ public function run(): void
}
} else {
$this->command->error("❌ Failed to import: {$meme_record['filename']} - Import returned false");
$this->command->error("🛑 Halting seeder to investigate the issue");
$this->command->error('🛑 Halting seeder to investigate the issue');
throw new \RuntimeException("Import failed for {$meme_record['filename']}");
}
} catch (\Exception $e) {
$this->command->error("❌ Failed to import: {$meme_record['filename']} - {$e->getMessage()}");
$this->command->error("🛑 Halting seeder to investigate the issue");
$this->command->error('🛑 Halting seeder to investigate the issue');
throw $e;
}
}
@@ -146,7 +147,7 @@ private function parseCsvFile(string $csv_path): array
$collection = Excel::toCollection(null, $csv_path)->first();
if ($collection->isEmpty()) {
throw new \RuntimeException("CSV file is empty or could not be parsed");
throw new \RuntimeException('CSV file is empty or could not be parsed');
}
// Get headers from first row
@@ -253,12 +254,12 @@ private function importSingleMeme(array $meme_record): bool
// Check for null description before creating record
if ($meme_record['description'] === null) {
$this->command->error("❌ NULL DESCRIPTION DETECTED:");
$this->command->error('❌ NULL DESCRIPTION DETECTED:');
$this->command->error(" Filename: {$meme_record['filename']}");
$this->command->error(" Name: {$meme_record['name']}");
$this->command->error(" Description field is NULL in CSV data");
$this->command->error(" CSV row data: " . json_encode($meme_record));
$this->command->error("🛑 HALTING SEEDER - FIX THE CSV DATA");
$this->command->error(' Description field is NULL in CSV data');
$this->command->error(' CSV row data: '.json_encode($meme_record));
$this->command->error('🛑 HALTING SEEDER - FIX THE CSV DATA');
throw new \RuntimeException("NULL description found for {$meme_record['filename']} - CSV data needs to be fixed");
}

View File

@@ -5,27 +5,28 @@ const FAQDiscord = () => {
const faqData = [
{
q: 'How can I create a meme video?',
a: 'Use the video editor on top to start making your meme! Edit your caption, background and meme. Once satisfied, press the Export button to download your video!',
},
{
q: 'What features are available now?',
a: 'At the moment, All 200+ meme templates and 200+ backgrounds are completely free! We will be adding more memes and backgrounds to the library soon!',
a: 'Use the video editor on top to start making your meme!<br><br>Edit your caption, background and meme. Once satisfied, press the Export button to download your video!',
},
{
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.',
a: "Video processing happens entirely in your browser using advanced web technology.<br><br> 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. <br><br>If your phone is too slow, it's probably a potato. Try using a faster device like a desktop computer for better performance.",
},
{
q: 'What is a potato device?',
a: `Potato devices are old, dated computers, laptops, phones or tablets with little RAM and CPU power - typically devices from before ${new Date().getFullYear() - 6} (pre-${new Date().getFullYear() - 6}).<br><br>These devices are usually too weak for the modern web and may not work properly with our video editor, or may crash during video processing.`,
},
{
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.',
a: 'We export high-quality MP4 videos optimized for all social media platforms in 9:16 format.<br><br>This is compatible for TikTok, Youtube Shorts, Instagram Reels, and more.',
},
{
q: 'Is there a mobile app?',
a: "Our web app is fully responsive and works perfectly on mobile devices. Do you want a mobile app? We'll see what can be done. Let us know in our Discord group.",
a: "Our web app is fully responsive and works perfectly on mobile devices.<br><br>Do you want a mobile app? We'll see what can be done. Let us know in our Discord group.",
},
{
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.',
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!<br><br>Want a certain content? Let us know in our Discord group.',
},
{
q: 'I have more questions!',
@@ -49,7 +50,9 @@ const FAQDiscord = () => {
{faqData.map((faq, index) => (
<AccordionItem key={index} value={`item-${index + 1}`} className="border-b last:border-b-0">
<AccordionTrigger className="py-4 text-left font-medium hover:no-underline">{faq.q}</AccordionTrigger>
<AccordionContent className="text-muted-foreground pb-4 leading-relaxed text-balance">{faq.a}</AccordionContent>
<AccordionContent className="text-muted-foreground pb-4 leading-relaxed text-balance">
<div dangerouslySetInnerHTML={{ __html: faq.a }} />
</AccordionContent>
</AccordionItem>
))}
</Accordion>

View File

@@ -4,28 +4,31 @@ const Features = () => {
const features = [
{
icon: Video,
title: 'Web-powered Video Editor',
description: 'Easy video editor with editable text, background, memes, built into the web. No additional software required.',
title: 'No installation needed',
description: 'Easy video editor with editable text, background, memes, built into the web.',
gradient: 'bg-gradient-to-br from-transparent to-blue-500/5 dark:to-blue-400/10 hover:bg-gradient-to-tl',
order: 3,
},
{
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',
order: 1,
},
{
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',
order: 2,
},
{
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',
order: 4,
},
{
icon: Library,
@@ -33,6 +36,7 @@ const Features = () => {
description: 'Soon we will be adding more memes and backgrounds to the library!',
comingSoon: true,
gradient: 'bg-gradient-to-br from-transparent to-orange-500/5 dark:to-orange-400/10 hover:bg-gradient-to-tl',
order: 5,
},
];
@@ -40,7 +44,9 @@ const Features = () => {
<section className="">
<div className="mx-auto max-w-6xl space-y-10 px-4 sm:px-6 lg:px-8">
<div className="flex flex-wrap justify-center gap-3 md:grid-cols-2 lg:grid-cols-3 lg:gap-4">
{features.map((feature, index) => (
{features
.sort((a, b) => a.order - b.order)
.map((feature, index) => (
<div
key={index}
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`}

View File

@@ -8,7 +8,7 @@ const Hero = () => {
{/* Badge */}
<div className="bg-background/50 inline-flex items-center gap-2 rounded-full border px-3 py-1 text-sm backdrop-blur-sm">
<div className="h-2 w-2 rounded-full bg-green-500"></div>
<span className="text-muted-foreground">Free meme videos No signup required</span>
<span className="text-muted-foreground">Instant meme videos No signup required</span>
</div>
{/* Main heading */}
@@ -19,7 +19,7 @@ const Hero = () => {
</h1>
<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
Fast and simple meme video editor
</h2>
</div>

File diff suppressed because one or more lines are too long