This commit is contained in:
ct
2025-07-15 02:56:39 +08:00
parent d57c75d5d7
commit 31383349c2
8 changed files with 116 additions and 35 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -71,14 +71,14 @@ public function searchMemes(Request $request)
->where(function ($q) use ($query) { ->where(function ($q) use ($query) {
// Search in name and description using ILIKE for partial matches // Search in name and description using ILIKE for partial matches
$q->where('name', 'ILIKE', "%{$query}%") $q->where('name', 'ILIKE', "%{$query}%")
->orWhere('description', 'ILIKE', "%{$query}%") ->orWhere('description', 'ILIKE', "%{$query}%")
// Search in JSON arrays using PostgreSQL JSON operators // Search in JSON arrays using PostgreSQL JSON operators
->orWhereRaw("keywords::text ILIKE ?", ["%{$query}%"]) ->orWhereRaw('keywords::text ILIKE ?', ["%{$query}%"])
->orWhereRaw("action_keywords::text ILIKE ?", ["%{$query}%"]) ->orWhereRaw('action_keywords::text ILIKE ?', ["%{$query}%"])
->orWhereRaw("emotion_keywords::text ILIKE ?", ["%{$query}%"]) ->orWhereRaw('emotion_keywords::text ILIKE ?', ["%{$query}%"])
->orWhereRaw("misc_keywords::text ILIKE ?", ["%{$query}%"]); ->orWhereRaw('misc_keywords::text ILIKE ?', ["%{$query}%"]);
}) })
->orderByRaw(" ->orderByRaw('
CASE CASE
WHEN name ILIKE ? THEN 1 WHEN name ILIKE ? THEN 1
WHEN description ILIKE ? THEN 2 WHEN description ILIKE ? THEN 2
@@ -88,7 +88,7 @@ public function searchMemes(Request $request)
WHEN misc_keywords::text ILIKE ? THEN 6 WHEN misc_keywords::text ILIKE ? THEN 6
ELSE 7 ELSE 7
END, name ASC END, name ASC
", ["%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%"]) ', ["%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%"])
->take($limit) ->take($limit)
->get(); ->get();
} }
@@ -115,12 +115,12 @@ public function searchBackgrounds(Request $request)
// Search in prompt field using ILIKE for partial matches // Search in prompt field using ILIKE for partial matches
$backgrounds = BackgroundMedia::where('status', 'completed') $backgrounds = BackgroundMedia::where('status', 'completed')
->where('prompt', 'ILIKE', "%{$query}%") ->where('prompt', 'ILIKE', "%{$query}%")
->orderByRaw(" ->orderByRaw('
CASE CASE
WHEN prompt ILIKE ? THEN 1 WHEN prompt ILIKE ? THEN 1
ELSE 2 ELSE 2
END, prompt ASC END, prompt ASC
", ["%{$query}%"]) ', ["%{$query}%"])
->take($limit) ->take($limit)
->get(); ->get();
} }

View File

@@ -8,7 +8,7 @@ import { ErrorBoundary } from 'react-error-boundary';
import { GA4Provider } from '@/plugins/GA4Context.jsx'; // Updated import import { GA4Provider } from '@/plugins/GA4Context.jsx'; // Updated import
import DetailedErrorFallback from './components/custom/detailed-error-fallback'; // Import your component import DetailedErrorFallback from './components/custom/detailed-error-fallback'; // Import your component
import { Toaster } from './components/ui/sonner'; import { Toaster } from './components/ui/sonner';
import { initializeTheme } from './hooks/use-appearance'; import { useTheme } from './hooks/useTheme';
import AuthDialog from './modules/auth/AuthDialog'; import AuthDialog from './modules/auth/AuthDialog';
import { AxiosProvider } from './plugins/AxiosContext'; import { AxiosProvider } from './plugins/AxiosContext';
import { MittProvider } from './plugins/MittContext'; import { MittProvider } from './plugins/MittContext';
@@ -56,4 +56,4 @@ createInertiaApp({
}, },
}); });
initializeTheme(); // Theme is now handled by useTheme hook in components

View File

@@ -0,0 +1,61 @@
import { useEffect, useState } from 'react';
export function useTheme() {
const [theme, setTheme] = useState('system');
const [isDark, setIsDark] = useState(false);
useEffect(() => {
// Get theme from session storage or default to system
const savedTheme = sessionStorage.getItem('theme') || 'system';
setTheme(savedTheme);
const updateTheme = (themeValue) => {
const root = document.documentElement;
if (themeValue === 'system') {
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setIsDark(systemPrefersDark);
root.classList.toggle('dark', systemPrefersDark);
} else {
const shouldBeDark = themeValue === 'dark';
setIsDark(shouldBeDark);
root.classList.toggle('dark', shouldBeDark);
}
};
// Apply initial theme
updateTheme(savedTheme);
// Listen for system theme changes when using system theme
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleSystemThemeChange = () => {
if (theme === 'system') {
updateTheme('system');
}
};
mediaQuery.addEventListener('change', handleSystemThemeChange);
return () => {
mediaQuery.removeEventListener('change', handleSystemThemeChange);
};
}, [theme]);
const toggleTheme = () => {
const newTheme = isDark ? 'light' : 'dark';
setTheme(newTheme);
sessionStorage.setItem('theme', newTheme);
};
const resetToSystem = () => {
setTheme('system');
sessionStorage.removeItem('theme');
};
return {
theme,
isDark,
toggleTheme,
resetToSystem,
};
}

View File

@@ -77,15 +77,17 @@ const FAQDiscord = () => {
</div> </div>
</div> </div>
<a {import.meta.env.VITE_DISCORD_LINK && (
href="https://discord.gg/YxKPrtPGZ2" <a
target="_blank" href={import.meta.env.VITE_DISCORD_LINK}
rel="noopener noreferrer" target="_blank"
className="inline-flex items-center justify-center gap-2 rounded-full bg-[#5865F2] px-8 py-3 text-lg font-semibold text-white shadow-lg transition-all hover:bg-[#4752C4] hover:shadow-xl focus:ring-2 focus:ring-[#5865F2] focus:ring-offset-2 focus:outline-none" rel="noopener noreferrer"
> className="inline-flex items-center justify-center gap-2 rounded-full bg-[#5865F2] px-8 py-3 text-lg font-semibold text-white shadow-lg transition-all hover:bg-[#4752C4] hover:shadow-xl focus:ring-2 focus:ring-[#5865F2] focus:ring-offset-2 focus:outline-none"
Join Discord >
<ExternalLinkIcon className="h-5 w-5" /> Join Discord
</a> <ExternalLinkIcon className="h-5 w-5" />
</a>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,10 @@
import { Switch } from '@/components/ui/switch';
import { useTheme } from '@/hooks/useTheme';
import { Sun, Moon } from 'lucide-react';
const Footer = () => { const Footer = () => {
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
const { isDark, toggleTheme } = useTheme();
return ( return (
<section className="pt-10"> <section className="pt-10">
@@ -7,7 +12,16 @@ const Footer = () => {
<div className="border-t pt-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="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} MEMEFAST. All rights reserved.</div> <div className="text-muted-foreground text-sm">© {currentYear} MEMEFAST. All rights reserved.</div>
<div className="flex space-x-6"> <div className="flex flex-col items-center space-y-4 sm:flex-row sm:space-y-0 sm:space-x-6">
{/* Theme Toggle */}
<div className="flex items-center space-x-2">
<Sun className="h-4 w-4 text-muted-foreground" />
<Switch id="dark-mode" checked={isDark} onCheckedChange={toggleTheme} />
<Moon className="h-4 w-4 text-muted-foreground" />
</div>
{/* Navigation Links */}
<div className="flex space-x-6">
<a href="/" className="text-muted-foreground hover:text-foreground text-sm transition-colors"> <a href="/" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Home Home
</a> </a>
@@ -17,14 +31,17 @@ const Footer = () => {
<a href="/privacy" className="text-muted-foreground hover:text-foreground text-sm transition-colors"> <a href="/privacy" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Privacy Privacy
</a> </a>
<a {import.meta.env.VITE_DISCORD_LINK && (
href="https://discord.gg/YxKPrtPGZ2" <a
target="_blank" href={import.meta.env.VITE_DISCORD_LINK}
rel="noopener noreferrer" target="_blank"
className="text-muted-foreground hover:text-foreground text-sm transition-colors" rel="noopener noreferrer"
> className="text-muted-foreground hover:text-foreground text-sm transition-colors"
Discord >
</a> Discord
</a>
)}
</div>
</div> </div>
</div> </div>
</div> </div>

File diff suppressed because one or more lines are too long

View File

@@ -1,21 +1,22 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" @class(['dark' => ($appearance ?? 'system') == 'dark'])> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
{{-- Inline script to detect system dark mode preference and apply it immediately --}} {{-- Inline script to detect theme preference and apply it immediately to prevent flash --}}
<script> <script>
(function() { (function() {
const appearance = '{{ $appearance ?? 'system' }}'; const savedTheme = sessionStorage.getItem('theme') || 'system';
if (appearance === 'system') { if (savedTheme === 'system') {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDark) { if (prefersDark) {
document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark');
} }
} else if (savedTheme === 'dark') {
document.documentElement.classList.add('dark');
} }
})(); })();
</script> </script>