From 3ce2493c488ce9ead8d10394df6680d8b2754ea6 Mon Sep 17 00:00:00 2001 From: Bowen Han Date: Fri, 29 Aug 2025 17:00:05 -0700 Subject: [PATCH] chore: translate comments --- backgroundworker/prisma.config.ts | 2 +- middleware.ts | 6 ++--- prisma.config.ts | 2 +- src/app/api/settings/route.ts | 6 ++--- src/app/api/settings/sync/route.ts | 16 ++++++------- src/app/api/user/profile/route.ts | 2 +- src/app/api/user/tokens/route.ts | 10 ++++---- src/app/componments/settings/Settings.css | 10 ++++---- src/app/componments/settings/settingsAPI.ts | 8 +++---- .../settings/settingsSyncManager.ts | 16 ++++++------- .../settings/settingsSyncManagerNew.ts | 16 ++++++------- src/app/componments/todo/TodoTypes.ts | 18 +++++++------- src/app/lib/cors.ts | 24 +++++++++---------- src/app/lib/database.ts | 12 +++++----- src/app/lib/jwt.ts | 20 ++++++++-------- src/app/test-toast-simple/page.tsx | 4 ++-- tailwind.config.js | 6 ++--- 17 files changed, 89 insertions(+), 89 deletions(-) diff --git a/backgroundworker/prisma.config.ts b/backgroundworker/prisma.config.ts index 379dbe2..2718974 100644 --- a/backgroundworker/prisma.config.ts +++ b/backgroundworker/prisma.config.ts @@ -3,7 +3,7 @@ import { PrismaD1 } from '@prisma/adapter-d1'; import { config } from 'dotenv'; import { resolve } from 'path'; -// 加载环境变量,优先读取.env.local,然后.env +// Load environment variables, preferring .env.local over .env config({ path: resolve(process.cwd(), '../.env.local') }); config({ path: resolve(process.cwd(), '../.env') }); diff --git a/middleware.ts b/middleware.ts index 30d9ed3..a6bbe7f 100644 --- a/middleware.ts +++ b/middleware.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server' import { getCorsHeaders, getCorsOptionsHeaders } from './src/app/lib/cors' export function middleware(request: NextRequest) { - // 处理所有API路由的CORS预检请求 + // Handle CORS preflight requests for all API routes if (request.method === 'OPTIONS' && request.nextUrl.pathname.startsWith('/api/')) { return new NextResponse(null, { status: 200, @@ -10,10 +10,10 @@ export function middleware(request: NextRequest) { }) } - // 对于其他请求,继续处理 + // Continue processing other requests const response = NextResponse.next() - // 为所有API响应添加CORS头 + // Add CORS headers to all API responses if (request.nextUrl.pathname.startsWith('/api/')) { const corsHeaders = getCorsHeaders(request) Object.entries(corsHeaders).forEach(([key, value]) => { diff --git a/prisma.config.ts b/prisma.config.ts index 3087c19..bb8d16c 100644 --- a/prisma.config.ts +++ b/prisma.config.ts @@ -3,7 +3,7 @@ import { PrismaD1 } from '@prisma/adapter-d1'; import { config } from 'dotenv'; import { resolve } from 'path'; -// 加载环境变量,优先读取.env.local,然后.env +// Load environment variables, preferring .env.local over .env config({ path: resolve(process.cwd(), '.env.local') }); config({ path: resolve(process.cwd(), '.env') }); diff --git a/src/app/api/settings/route.ts b/src/app/api/settings/route.ts index 1508207..1fbd34e 100644 --- a/src/app/api/settings/route.ts +++ b/src/app/api/settings/route.ts @@ -2,11 +2,11 @@ import { NextRequest, NextResponse } from 'next/server'; import { withAuth } from '../../lib/auth'; import type { JWTPayload, SettingsResponse, UserSettings } from '../../types/api'; -// 获取用户设置 +// Fetch user settings async function handleGetSettings(request: NextRequest, user: JWTPayload): Promise { try { - // TODO: 从数据库获取用户设置 - // 暂时返回默认设置 + // TODO: Retrieve user settings from the database + // Temporarily return default settings const settings: UserSettings = { pomodoro_duration: 1500, short_break_duration: 300, diff --git a/src/app/api/settings/sync/route.ts b/src/app/api/settings/sync/route.ts index 96a2164..a0946de 100644 --- a/src/app/api/settings/sync/route.ts +++ b/src/app/api/settings/sync/route.ts @@ -2,14 +2,14 @@ import { NextRequest, NextResponse } from 'next/server'; import { withAuth } from '../../../lib/auth'; import type { JWTPayload, SyncOperationsRequest, SyncResponse, UserSettings } from '../../../types/api'; -// 同步设置操作 +// Sync settings operations async function handleSyncSettings(request: NextRequest, user: JWTPayload): Promise { try { const { operations, lastSyncTime } = await request.json() as SyncOperationsRequest; const userId = user.sub; - // TODO: 应用所有操作到数据库 - // 暂时跳过数据库操作,只记录日志 + // TODO: Apply all operations to the database + // Temporarily skip database operations; just log them for (const operation of operations) { console.log(`Processing settings operation: ${operation.type}`, { payload: operation.payload, @@ -17,12 +17,12 @@ async function handleSyncSettings(request: NextRequest, user: JWTPayload): Promi userId }); - // 这里应该执行实际的数据库操作 + // Actual database operations should be executed here // await settingsService.applySettingsOperation(userId, operation); } - // TODO: 获取更新后的设置 - // 暂时返回默认设置 + // TODO: Fetch updated settings + // Temporarily return default settings const settings: UserSettings = { pomodoro_duration: 1500, short_break_duration: 300, @@ -37,8 +37,8 @@ async function handleSyncSettings(request: NextRequest, user: JWTPayload): Promi const response: SyncResponse = { success: true, data: { - conflicts: [], // 设置通常不会有冲突 - serverOperations: [], // 暂时不需要返回服务端操作 + conflicts: [], // Settings typically have no conflicts + serverOperations: [], // No server operations need to be returned for now lastSyncTime: syncTime, settings } diff --git a/src/app/api/user/profile/route.ts b/src/app/api/user/profile/route.ts index 62a2d59..3ba4ee0 100644 --- a/src/app/api/user/profile/route.ts +++ b/src/app/api/user/profile/route.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { withAuth } from '../../../lib/auth'; import type { JWTPayload } from '../../../types/api'; -// 获取用户信息 +// Fetch user information async function handleGetUserProfile(request: NextRequest, user: JWTPayload): Promise { try { return NextResponse.json({ diff --git a/src/app/api/user/tokens/route.ts b/src/app/api/user/tokens/route.ts index 25cca67..0c0233b 100644 --- a/src/app/api/user/tokens/route.ts +++ b/src/app/api/user/tokens/route.ts @@ -5,7 +5,7 @@ import { getCorsHeaders } from '../../../lib/cors'; export async function GET(request: NextRequest) { try { - // 验证JWT token + // Validate JWT token const authHeader = request.headers.get('Authorization'); if (!authHeader || !authHeader.startsWith('Bearer ')) { return NextResponse.json( @@ -30,7 +30,7 @@ export async function GET(request: NextRequest) { ); } - // 从数据库获取用户信息 + // Retrieve user information from the database const db = getDb(); const user = await db.user.findUnique({ where: { id: decoded.sub } @@ -46,7 +46,7 @@ export async function GET(request: NextRequest) { ); } - // 检查token是否过期 (使用类型断言来访问可能的字段) + // Check whether the token has expired (using type assertion to access possible fields) interface UserTokenFields { googleAccessToken: string | null; googleRefreshToken: string | null; @@ -67,7 +67,7 @@ export async function GET(request: NextRequest) { hasGoogleRefreshToken: !!userWithTokens.googleRefreshToken, tokenExpiry: userWithTokens.googleTokenExpiry, isTokenExpired, - // 不返回实际的token值,只返回是否存在 + // Return only whether tokens exist, not their actual values } }, { headers: getCorsHeaders(request) @@ -85,7 +85,7 @@ export async function GET(request: NextRequest) { } } -// 处理CORS预检请求 +// Handle CORS preflight requests export async function OPTIONS(request: NextRequest) { return new NextResponse(null, { status: 200, diff --git a/src/app/componments/settings/Settings.css b/src/app/componments/settings/Settings.css index e8ee82a..813d6df 100644 --- a/src/app/componments/settings/Settings.css +++ b/src/app/componments/settings/Settings.css @@ -4,9 +4,9 @@ @import '../common/forms.css'; @import '../common/states.css'; -/* ===== 设置组件样式 ===== */ +/* ===== Settings component styles ===== */ -/* 设置界面样式 */ +/* Settings interface styles */ .settings-modal { background: var(--gradient-gray); border-radius: var(--radius-2xl); @@ -215,10 +215,10 @@ border-top: 1px solid var(--color-gray-200); } -/* ===== 设置组件特定样式 ===== */ -/* 使用通用按钮样式,并为设置组件添加特定样式 */ +/* ===== Settings component specific styles ===== */ +/* Use common button styles and add settings-specific styles */ -/* ===== 响应式设计 ===== */ +/* ===== Responsive design ===== */ @media (max-width: var(--breakpoint-tablet)) { .settings-modal { max-width: 95vw; diff --git a/src/app/componments/settings/settingsAPI.ts b/src/app/componments/settings/settingsAPI.ts index 10e9c30..b781798 100644 --- a/src/app/componments/settings/settingsAPI.ts +++ b/src/app/componments/settings/settingsAPI.ts @@ -1,4 +1,4 @@ -// Settings API接口类型定义 +// Settings API interface type definitions export interface SettingsPayload { value: number | boolean | string } @@ -7,7 +7,7 @@ export interface SettingsOperation { type: string payload: SettingsPayload timestamp: string - id?: string // 本地操作ID,用于去重 + id?: string // Local operation ID for deduplication } export interface SettingsSyncRequest { @@ -161,7 +161,7 @@ class SettingsAPI { } } -// 单例管理 +// Singleton management let settingsAPIInstance: SettingsAPI | null = null; export const getSettingsAPI = () => { @@ -171,7 +171,7 @@ export const getSettingsAPI = () => { return settingsAPIInstance; }; -// 为了向后兼容 +// For backward compatibility export const settingsAPI = { get instance() { return getSettingsAPI(); diff --git a/src/app/componments/settings/settingsSyncManager.ts b/src/app/componments/settings/settingsSyncManager.ts index 4c3e5ca..2a72368 100644 --- a/src/app/componments/settings/settingsSyncManager.ts +++ b/src/app/componments/settings/settingsSyncManager.ts @@ -12,10 +12,10 @@ import { replaceSettings } from '../clock/ClockSlice' -// Settings API适配器 +// Settings API adapter class SettingsAPIAdapter implements SyncAPI { async syncOperations(operations: SyncOperation[], lastSyncTime: string | null) { - // 转换为SettingsOperation类型 + // Convert to SettingsOperation type const settingsOperations: SettingsOperation[] = operations.map(op => ({ type: op.type, payload: op.payload as SettingsPayload, @@ -38,12 +38,12 @@ class SettingsAPIAdapter implements SyncAPI { } } -// Settings操作处理器 +// Settings operation handler class SettingsOperationHandler implements OperationHandler { applyOperation(operation: SyncOperation) { const { type, payload } = operation - // 类型断言,因为我们知道不同操作类型的payload结构 + // Type assertion since we know payload structures for different operation types const typedPayload = payload as { value: number | boolean | string }; switch (type) { @@ -71,7 +71,7 @@ class SettingsOperationHandler implements OperationHandler { } replaceData(data: unknown) { - // 使用服务端设置更新本地状态 + // Update local state with server settings const typedData = data as { settings: SettingsUpdate; lastSyncTime: string }; store.dispatch(replaceSettings({ settings: typedData.settings, @@ -80,13 +80,13 @@ class SettingsOperationHandler implements OperationHandler { } } -// 创建Settings同步管理器实例 +// Create Settings sync manager instance export const settingsSyncManager = new GenericSyncManager( 'settings', new SettingsAPIAdapter(), new SettingsOperationHandler(), - 10000 // 10秒同步间隔,设置同步频率较高 + 10000 // 10-second sync interval for frequent synchronization ) -// 为了保持向后兼容,提供一个包装方法 +// Wrapper method to maintain backward compatibility export const fetchSettingsFromServer = () => settingsSyncManager.fetchDataFromServer() diff --git a/src/app/componments/settings/settingsSyncManagerNew.ts b/src/app/componments/settings/settingsSyncManagerNew.ts index 2b24cd7..2ee9e53 100644 --- a/src/app/componments/settings/settingsSyncManagerNew.ts +++ b/src/app/componments/settings/settingsSyncManagerNew.ts @@ -12,10 +12,10 @@ import { replaceSettings } from '../clock/ClockSlice' -// Settings API适配器 +// Settings API adapter class SettingsAPIAdapter implements SyncAPI { async syncOperations(operations: SyncOperation[], lastSyncTime: string | null) { - // 转换为SettingsOperation类型 + // Convert to SettingsOperation type const settingsOperations: SettingsOperation[] = operations.map(op => ({ type: op.type, payload: op.payload as SettingsPayload, @@ -38,12 +38,12 @@ class SettingsAPIAdapter implements SyncAPI { } } -// Settings操作处理器 +// Settings operation handler class SettingsOperationHandler implements OperationHandler { applyOperation(operation: SyncOperation) { const { type, payload } = operation - // 类型断言,因为我们知道不同操作类型的payload结构 + // Type assertion since we know payload structures for different operation types const typedPayload = payload as { value: number | boolean | string }; switch (type) { @@ -71,7 +71,7 @@ class SettingsOperationHandler implements OperationHandler { } replaceData(data: unknown) { - // 使用服务端设置更新本地状态 + // Update local state with server settings const typedData = data as { settings: SettingsUpdate; lastSyncTime: string }; store.dispatch(replaceSettings({ settings: typedData.settings, @@ -80,13 +80,13 @@ class SettingsOperationHandler implements OperationHandler { } } -// 创建Settings同步管理器实例 +// Create Settings sync manager instance export const settingsSyncManager = new GenericSyncManager( 'settings', new SettingsAPIAdapter(), new SettingsOperationHandler(), - 10000 // 10秒同步间隔,设置同步频率较高 + 10000 // 10-second sync interval for frequent synchronization ) -// 为了保持向后兼容,提供一个包装方法 +// Wrapper method to maintain backward compatibility export const fetchSettingsFromServer = () => settingsSyncManager.fetchDataFromServer() diff --git a/src/app/componments/todo/TodoTypes.ts b/src/app/componments/todo/TodoTypes.ts index 36fd7fe..f2d4b3a 100644 --- a/src/app/componments/todo/TodoTypes.ts +++ b/src/app/componments/todo/TodoTypes.ts @@ -8,13 +8,13 @@ import {todoSyncActions} from "./todoSyncActions"; export interface RootProps { } -// 过滤后的Todo项目接口,只包含符合过滤条件的subtodo +// Filtered Todo item interface that only includes subtodos matching the filter export interface FilteredTodoItem extends Omit { subItems: SubTodoItem[]; - originalSubItems: SubTodoItem[]; // 保存原始的subItems用于编辑等操作 + originalSubItems: SubTodoItem[]; // Preserve original subItems for editing and other operations } -// 检查todo是否包含指定状态的subtodo +// Check whether a todo contains subtodos with the specified status const hasSubtodosWithStatus = (todo: TodoItem, completed: boolean): boolean => { if (!todo.subItems || todo.subItems.length === 0) { return false; @@ -22,7 +22,7 @@ const hasSubtodosWithStatus = (todo: TodoItem, completed: boolean): boolean => { return todo.subItems.some((subTodo: SubTodoItem) => subTodo.completed === completed && !subTodo.deleted); }; -// 根据filter过滤subtodo +// Filter subtodos according to the filter const filterSubtodos = (subItems: SubTodoItem[], filter: VisibilityFilters): SubTodoItem[] => { if (!subItems || subItems.length === 0) { return []; @@ -40,7 +40,7 @@ const filterSubtodos = (subItems: SubTodoItem[], filter: VisibilityFilters): Sub } }; -// 检查todo是否应该根据filter显示 +// Determine whether a todo should be displayed based on the filter const shouldShowTodo = (todo: TodoItem, filter: VisibilityFilters): boolean => { if (todo.deleted) return false; @@ -48,10 +48,10 @@ const shouldShowTodo = (todo: TodoItem, filter: VisibilityFilters): boolean => { case VisibilityFilters.SHOW_ALL: return true; case VisibilityFilters.SHOW_COMPLETED: - // 显示所有已完成的subtodo的todo,或者主todo已完成 + // Show todos with all subtodos completed, or if the main todo is completed return todo.completed || hasSubtodosWithStatus(todo, true); case VisibilityFilters.SHOW_ACTIVE: - // 显示所有包含未完成subtodo的todo,或者主todo未完成 + // Show todos containing unfinished subtodos, or if the main todo is incomplete return !todo.completed || hasSubtodosWithStatus(todo, false); default: return true; @@ -61,14 +61,14 @@ const shouldShowTodo = (todo: TodoItem, filter: VisibilityFilters): boolean => { const getVisibleTodos = (todos: TodoItem[], filter: VisibilityFilters): FilteredTodoItem[] => { const visibleTodos = todos.filter(todo => shouldShowTodo(todo, filter)); - // 为每个可见的todo创建过滤后的版本 + // Create a filtered version for each visible todo const result = visibleTodos.map(todo => { const filteredSubItems = filterSubtodos(todo.subItems, filter); //console.log(`[getVisibleTodos] Todo "${todo.text}": original subtodos: ${todo.subItems.length}, filtered subtodos: ${filteredSubItems.length}`); return { ...todo, subItems: filteredSubItems, - originalSubItems: todo.subItems // 保存原始数据 + originalSubItems: todo.subItems // Save original data }; }); diff --git a/src/app/lib/cors.ts b/src/app/lib/cors.ts index 65d0ce9..2c7c2d2 100644 --- a/src/app/lib/cors.ts +++ b/src/app/lib/cors.ts @@ -1,10 +1,10 @@ import { NextRequest } from 'next/server'; /** - * 获取CORS头部配置 - * @param request NextRequest对象 - * @param additionalHeaders 额外的头部配置 - * @returns 头部配置对象 + * Get CORS header configuration + * @param request NextRequest object + * @param additionalHeaders Additional headers + * @returns Header configuration object */ export function getCorsHeaders( request: NextRequest, @@ -22,26 +22,26 @@ export function getCorsHeaders( } /** - * 获取预检请求的CORS头部配置 - * @param request NextRequest对象 - * @returns 头部配置对象 + * Get CORS headers for preflight requests + * @param request NextRequest object + * @returns Header configuration object */ export function getCorsOptionsHeaders(request: NextRequest): Record { const headers: Record = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - 'Access-Control-Max-Age': '86400', // 24小时缓存预检结果 + 'Access-Control-Max-Age': '86400', // Cache preflight results for 24 hours }; return headers; } /** - * 检查请求来源是否被允许 (现在允许所有来源) - * @param request NextRequest对象 - * @returns 始终返回true,允许所有来源 + * Check whether the request origin is allowed (currently allows all origins) + * @param request NextRequest object + * @returns Always true, allowing all origins */ export function isOriginAllowed(request: NextRequest): boolean { - return true; // 允许所有来源 + return true; // Allow all origins } diff --git a/src/app/lib/database.ts b/src/app/lib/database.ts index 966860f..f15d9ec 100644 --- a/src/app/lib/database.ts +++ b/src/app/lib/database.ts @@ -3,11 +3,11 @@ import { PrismaClient } from "@prisma/client"; import { PrismaD1 } from "@prisma/adapter-d1"; import { cache } from "react"; -// 获取数据库客户端 - 用于动态路由 +// Get database client - for dynamic routes export const getDb = cache(() => { try { const { env } = getCloudflareContext() as { env: CloudflareEnv }; - // 从Cloudflare环境变量获取D1数据库绑定 + // Retrieve the D1 database binding from Cloudflare environment variables const d1Database = env.DB; if (!d1Database) { throw new Error('D1 database not found in environment. Make sure DB binding is configured in wrangler.toml'); @@ -15,13 +15,13 @@ export const getDb = cache(() => { const adapter = new PrismaD1(d1Database); return new PrismaClient({ adapter }); } catch (error) { - // 在开发环境中,如果没有Cloudflare上下文,抛出错误 - // 因为我们需要D1数据库来工作 + // In development, throw an error if the Cloudflare context is missing + // because the D1 database is required to operate throw new Error(`Database connection failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }); -// 获取数据库客户端 - 用于静态路由 (ISR/SSG) +// Get database client - for static routes (ISR/SSG) export const getDbAsync = async () => { try { const { env } = await getCloudflareContext({ async: true }) as { env: CloudflareEnv }; @@ -36,7 +36,7 @@ export const getDbAsync = async () => { } }; -// 检查数据库是否已初始化 +// Check if the database has been initialized export function isDatabaseInitialized(): boolean { try { getDb(); diff --git a/src/app/lib/jwt.ts b/src/app/lib/jwt.ts index 79e42d3..74e5c19 100644 --- a/src/app/lib/jwt.ts +++ b/src/app/lib/jwt.ts @@ -3,7 +3,7 @@ import type { GoogleUserInfo, JWTPayload } from '../types/api'; const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key'; -// 生成JWT token +// Generate JWT token export function generateJWT(userInfo: GoogleUserInfo): string { const payload: JWTPayload = { sub: userInfo.sub, @@ -11,13 +11,13 @@ export function generateJWT(userInfo: GoogleUserInfo): string { name: userInfo.name, picture: userInfo.picture, iat: Math.floor(Date.now() / 1000), - exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // 24小时过期 + exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // Expires in 24 hours }; return jwt.sign(payload, JWT_SECRET, { algorithm: 'HS256' }); } -// 验证JWT token +// Verify JWT token export function verifyJWT(token: string): JWTPayload | null { try { const decoded = jwt.verify(token, JWT_SECRET) as JWTPayload; @@ -28,9 +28,9 @@ export function verifyJWT(token: string): JWTPayload | null { } } -// 验证Google JWT token +// Verify Google JWT token export function verifyGoogleToken(credential: string, googleClientId: string): GoogleUserInfo | null { - // 检查 Google Client ID 配置 + // Check Google Client ID configuration if (!googleClientId || googleClientId.trim() === '') { console.error('🔴 [JWT] Google Client ID is not configured'); console.error('🔴 [JWT] Please set GOOGLE_CLIENT_ID or NEXT_PUBLIC_GOOGLE_CLIENT_ID environment variable'); @@ -38,7 +38,7 @@ export function verifyGoogleToken(credential: string, googleClientId: string): G } try { - // 解码JWT payload(生产环境中应该验证签名) + // Decode JWT payload (signature should be verified in production) const payload = JSON.parse(Buffer.from(credential.split('.')[1], 'base64').toString()) as GoogleUserInfo; console.log('Token payload:', { @@ -51,17 +51,17 @@ export function verifyGoogleToken(credential: string, googleClientId: string): G email: payload.email }); - // 验证token是否过期 + // Check if the token has expired if (payload.exp && payload.exp < Date.now() / 1000) { throw new Error('Token expired'); } - // 验证issuer + // Validate issuer if (payload.iss !== 'accounts.google.com' && payload.iss !== 'https://accounts.google.com') { throw new Error('Invalid issuer'); } - // 验证audience(客户端ID)- 支持数组和字符串格式 + // Validate audience (client ID) - supports array and string formats let isValidAudience = false; if (Array.isArray(payload.aud)) { isValidAudience = payload.aud.includes(googleClientId); @@ -74,7 +74,7 @@ export function verifyGoogleToken(credential: string, googleClientId: string): G received: payload.aud, expected: googleClientId }); - // 暂时不抛出错误,用于调试 + // Temporarily do not throw an error for debugging // throw new Error('Invalid audience') } diff --git a/src/app/test-toast-simple/page.tsx b/src/app/test-toast-simple/page.tsx index f28fc8b..d14bedc 100644 --- a/src/app/test-toast-simple/page.tsx +++ b/src/app/test-toast-simple/page.tsx @@ -22,14 +22,14 @@ export default function TestToastSimplePage() { }; const testMultipleSuccess = () => { - // 模拟多次触发相同消息的情况 + // Simulate triggering the same message multiple times toastManager.successIntl('toast.test.successFirst'); setTimeout(() => toastManager.successIntl('toast.test.successSecond'), 100); setTimeout(() => toastManager.successIntl('toast.test.successThird'), 200); }; const testBackgroundColors = () => { - // 测试背景色是否正确显示 + // Test whether background colors display correctly toastManager.errorIntl('toast.test.backgroundRed'); setTimeout(() => toastManager.successIntl('toast.test.backgroundGreen'), 1000); setTimeout(() => toastManager.warningIntl('toast.test.backgroundYellow'), 2000); diff --git a/tailwind.config.js b/tailwind.config.js index a50d845..6282fce 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -44,11 +44,11 @@ module.exports = { }, }, plugins: [], - // 确保CSS兼容性 + // Ensure CSS compatibility corePlugins: { - preflight: true, // 确保基础样式重置生效 + preflight: true, // Ensure base style reset takes effect }, - // 如果需要支持较旧浏览器,可以禁用某些现代特性 + // Disable certain modern features if older browser support is needed future: { removeDeprecatedGapUtilities: true, purgeLayersByDefault: true,