From 7b30992971bb90c8bb1f21c5083cf727e7988fb0 Mon Sep 17 00:00:00 2001 From: wei840222 Date: Sun, 17 Aug 2025 22:53:19 +0800 Subject: [PATCH] feat(i18n): Update language handling and remove unused imports for improved performance --- src/app/api/discover/route.ts | 10 +++------- src/app/library/page.tsx | 2 +- src/app/page.tsx | 2 +- src/app/settings/page.tsx | 3 +-- src/components/DeleteChat.tsx | 5 +++-- src/components/LocaleBootstrap.tsx | 2 -- src/components/MessageBox.tsx | 4 ++-- src/components/Navbar.tsx | 9 +-------- src/i18n/locales.ts | 2 +- src/lib/utils.ts | 23 ----------------------- 10 files changed, 13 insertions(+), 49 deletions(-) diff --git a/src/app/api/discover/route.ts b/src/app/api/discover/route.ts index c5119ea..0d06412 100644 --- a/src/app/api/discover/route.ts +++ b/src/app/api/discover/route.ts @@ -1,5 +1,5 @@ import { searchSearxng } from '@/lib/searxng'; -import { getLocale } from 'next-intl/server'; +import { DEFAULT_LOCALE } from '@/i18n/locales'; const websitesForTopic = { tech: { @@ -38,10 +38,6 @@ export const GET = async (req: Request) => { let data = []; - // derive base language from current locale (e.g., zh-TW -> zh) - const locale = await getLocale(); - const searxLanguage = 'en'; - if (mode === 'normal') { const seenUrls = new Set(); @@ -53,7 +49,7 @@ export const GET = async (req: Request) => { await searchSearxng(`site:${link} ${query}`, { engines: ['google news', 'bing news'], pageno: 1, - language: searxLanguage, + language: DEFAULT_LOCALE, }) ).results; }), @@ -75,7 +71,7 @@ export const GET = async (req: Request) => { { engines: ['google news', 'bing news'], pageno: 1, - language: searxLanguage, + language: DEFAULT_LOCALE, }, ) ).results; diff --git a/src/app/library/page.tsx b/src/app/library/page.tsx index 0f4f6c7..7d0407c 100644 --- a/src/app/library/page.tsx +++ b/src/app/library/page.tsx @@ -1,7 +1,7 @@ 'use client'; import DeleteChat from '@/components/DeleteChat'; -import { cn, formatTimeDifference, formatRelativeTime } from '@/lib/utils'; +import { cn, formatRelativeTime } from '@/lib/utils'; import { BookOpenText, ClockIcon, Delete, ScanEye } from 'lucide-react'; import Link from 'next/link'; import { useEffect, useState } from 'react'; diff --git a/src/app/page.tsx b/src/app/page.tsx index df49a07..430dd2f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,5 @@ import ChatWindow from '@/components/ChatWindow'; -import type { Metadata } from 'next'; +import { Metadata } from 'next'; import { Suspense } from 'react'; import { getTranslations } from 'next-intl/server'; diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 519a009..9ce4b31 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -9,7 +9,7 @@ import LocaleSwitcher from '@/components/LocaleSwitcher'; import { ImagesIcon, VideoIcon } from 'lucide-react'; import Link from 'next/link'; import { PROVIDER_METADATA } from '@/lib/providers'; -import { useLocale, useTranslations } from 'next-intl'; +import { useTranslations } from 'next-intl'; interface SettingsType { chatModelProviders: { @@ -131,7 +131,6 @@ const SettingsSection = ({ const Page = () => { const t = useTranslations('pages.settings'); - const locale = useLocale(); const [config, setConfig] = useState(null); const [chatModels, setChatModels] = useState>({}); const [embeddingModels, setEmbeddingModels] = useState>( diff --git a/src/components/DeleteChat.tsx b/src/components/DeleteChat.tsx index 23f9f5b..9f0c31e 100644 --- a/src/components/DeleteChat.tsx +++ b/src/components/DeleteChat.tsx @@ -39,7 +39,7 @@ const DeleteChat = ({ }); if (res.status != 200) { - throw new Error(t('common.errors.failedToDeleteChat')); + throw new Error('Failed to delete chat'); } const newChats = chats.filter((chat) => chat.id !== chatId); @@ -50,7 +50,8 @@ const DeleteChat = ({ window.location.href = '/'; } } catch (err: any) { - toast.error(err.message || t('common.errors.failedToDeleteChat')); + console.error(err); + toast.error(t('common.errors.failedToDeleteChat')); } finally { setConfirmationDialogOpen(false); setLoading(false); diff --git a/src/components/LocaleBootstrap.tsx b/src/components/LocaleBootstrap.tsx index de2e63c..85b3e48 100644 --- a/src/components/LocaleBootstrap.tsx +++ b/src/components/LocaleBootstrap.tsx @@ -9,10 +9,8 @@ export default function LocaleBootstrap({ initialLocale: AppLocale; }) { useEffect(() => { - // 若已有 cookie,跳過 const hasCookie = /(?:^|; )locale=/.test(document.cookie); if (hasCookie) return; - // 僅接受支援清單內的語系 const supported = new Set(LOCALES as readonly string[]); const loc = (initialLocale || DEFAULT_LOCALE) as string; const chosen = Array.from(supported).find( diff --git a/src/components/MessageBox.tsx b/src/components/MessageBox.tsx index 35573c7..7f26667 100644 --- a/src/components/MessageBox.tsx +++ b/src/components/MessageBox.tsx @@ -218,9 +218,9 @@ const MessageBox = ({ className="p-2 text-black/70 dark:text-white/70 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary transition duration-200 hover:text-black dark:hover:text-white" > {speechStatus === 'started' ? ( - + ) : ( - + )} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 950a590..787b5d2 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,11 +1,7 @@ import { Clock, Edit, Share, Trash, FileText, FileDown } from 'lucide-react'; import { Message } from './ChatWindow'; import { useEffect, useState, Fragment } from 'react'; -import { - formatTimeDifference, - formatRelativeTime, - formatDate, -} from '@/lib/utils'; +import { formatRelativeTime, formatDate } from '@/lib/utils'; import { useLocale, useTranslations } from 'next-intl'; import DeleteChat from './DeleteChat'; import { @@ -168,12 +164,9 @@ const Navbar = ({ ? `${messages[0].content.substring(0, 20).trim()}...` : messages[0].content; setTitle(newTitle); - // title already set above } }, [messages]); - // Removed per-locale relative time uses render-time computation - return (
= { de: 'Deutsch', }; -// Human-readable language name for prompt prefix +// Human-readable language name for prompt export function getPromptLanguageName(loc: string): string { const l = (loc || '').toLowerCase(); const match = ( diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 81c94fc..88de6e9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -19,29 +19,6 @@ export const formatDate = ( return new Intl.DateTimeFormat(locale || undefined, options).format(d); }; -export const formatTimeDifference = ( - date1: Date | string, - date2: Date | string, -): string => { - date1 = new Date(date1); - date2 = new Date(date2); - - const diffInSeconds = Math.floor( - Math.abs(date2.getTime() - date1.getTime()) / 1000, - ); - - if (diffInSeconds < 60) - return `${diffInSeconds} second${diffInSeconds !== 1 ? 's' : ''}`; - else if (diffInSeconds < 3600) - return `${Math.floor(diffInSeconds / 60)} minute${Math.floor(diffInSeconds / 60) !== 1 ? 's' : ''}`; - else if (diffInSeconds < 86400) - return `${Math.floor(diffInSeconds / 3600)} hour${Math.floor(diffInSeconds / 3600) !== 1 ? 's' : ''}`; - else if (diffInSeconds < 31536000) - return `${Math.floor(diffInSeconds / 86400)} day${Math.floor(diffInSeconds / 86400) !== 1 ? 's' : ''}`; - else - return `${Math.floor(diffInSeconds / 31536000)} year${Math.floor(diffInSeconds / 31536000) !== 1 ? 's' : ''}`; -}; - // Locale-aware relative time using Intl.RelativeTimeFormat export const formatRelativeTime = ( date1: Date | string,