153 lines
3.9 KiB
TypeScript
153 lines
3.9 KiB
TypeScript
import {
|
|
Box,
|
|
BarChart3,
|
|
Briefcase,
|
|
Clapperboard,
|
|
Edit,
|
|
Folder,
|
|
Home,
|
|
ImageIcon,
|
|
Monitor,
|
|
Moon,
|
|
Palette,
|
|
PlayCircle,
|
|
Plus,
|
|
Settings,
|
|
Sparkles,
|
|
Star,
|
|
Sun,
|
|
User,
|
|
Wand2,
|
|
Workflow,
|
|
type LucideIcon,
|
|
} from "lucide-react";
|
|
import type { LovartHomeSidebarItemKey } from "@/lib/home/lovart-sidebar-config";
|
|
import type { HomeUser } from "./types";
|
|
|
|
export type ThemeMode = "system" | "light" | "dark";
|
|
|
|
export const THEME_MODE_OPTIONS: Array<{
|
|
value: ThemeMode;
|
|
label: string;
|
|
description: string;
|
|
icon: LucideIcon;
|
|
}> = [
|
|
{
|
|
value: "system",
|
|
label: "跟随系统",
|
|
description: "随浏览器/系统深浅色自动切换",
|
|
icon: Monitor,
|
|
},
|
|
{
|
|
value: "light",
|
|
label: "浅色模式",
|
|
description: "始终使用明亮界面",
|
|
icon: Sun,
|
|
},
|
|
{
|
|
value: "dark",
|
|
label: "深色模式",
|
|
description: "始终使用暗色界面",
|
|
icon: Moon,
|
|
},
|
|
];
|
|
|
|
export const DISCOVERY_DEFAULT_TABS = [
|
|
"品牌设计",
|
|
"海报与广告",
|
|
"插画",
|
|
"UI设计",
|
|
"角色设计",
|
|
"影片与分镜",
|
|
"产品设计",
|
|
"建筑设计",
|
|
];
|
|
|
|
export const PROMPT_TAGS = [
|
|
{ key: "nanoBananaPro", label: "Nano Banana Pro", icon: Sparkles, highlighted: true },
|
|
{ key: "design", label: "Design", icon: ImageIcon, highlighted: false },
|
|
{ key: "branding", label: "Branding", icon: Star, highlighted: false },
|
|
{ key: "illustration", label: "Illustration", icon: Palette, highlighted: false },
|
|
{ key: "ecommerce", label: "E-Commerce", icon: Monitor, highlighted: false },
|
|
{ key: "video", label: "Video", icon: Clapperboard, highlighted: false },
|
|
] as const;
|
|
|
|
export const LOVART_HOME_SIDEBAR_FALLBACK_ICONS: Record<
|
|
LovartHomeSidebarItemKey,
|
|
LucideIcon
|
|
> = {
|
|
newProject: Plus,
|
|
home: Home,
|
|
projects: Folder,
|
|
profile: User,
|
|
gallery: ImageIcon,
|
|
tutorial: PlayCircle,
|
|
imageEditor: Edit,
|
|
aiCad: Box,
|
|
agent: Wand2,
|
|
videoCanvas: Clapperboard,
|
|
flowBoard: Workflow,
|
|
productPlanning: BarChart3,
|
|
toolbox1: Briefcase,
|
|
toolbox2: Briefcase,
|
|
settings: Settings,
|
|
};
|
|
|
|
export type LovartPromptTagKey = (typeof PROMPT_TAGS)[number]["key"];
|
|
export type LovartPromptTagVisibility = Record<LovartPromptTagKey, boolean>;
|
|
|
|
export const MASONRY_HEIGHTS = [420, 290, 340, 470, 300, 360, 430, 320];
|
|
export const FEATURED_PAGE_SIZE = 24;
|
|
export const COMPOSER_PREFIX_DEFAULT = "让Buyi-ai";
|
|
|
|
export function normalizeComposerPreviewTail(text: string, fixedPrefix: string) {
|
|
const trimmed = text.trim();
|
|
if (!trimmed) return "";
|
|
|
|
const sanitizedPrefix = fixedPrefix.trim();
|
|
if (sanitizedPrefix && trimmed.startsWith(sanitizedPrefix)) {
|
|
return trimmed.slice(sanitizedPrefix.length).trimStart();
|
|
}
|
|
|
|
const legacyPrefixRemoved = trimmed
|
|
.replace(/^让\s*buyi[-_ ]?ai\s*/i, "")
|
|
.replace(/^让\s*lovart\s*/i, "")
|
|
.trimStart();
|
|
if (legacyPrefixRemoved !== trimmed) {
|
|
return legacyPrefixRemoved;
|
|
}
|
|
|
|
return trimmed;
|
|
}
|
|
|
|
export function getUserInitials(user: HomeUser | null) {
|
|
const source = (user?.name || user?.email || "mu").trim();
|
|
if (!source) return "mu";
|
|
return source.slice(0, 2).toLowerCase();
|
|
}
|
|
|
|
export function formatRelativeTime(value?: string) {
|
|
if (!value) return "更新于今天";
|
|
const date = new Date(value);
|
|
if (Number.isNaN(date.getTime())) return "更新于今天";
|
|
const diffMs = Date.now() - date.getTime();
|
|
const minute = 60 * 1000;
|
|
const hour = 60 * minute;
|
|
const day = 24 * hour;
|
|
if (diffMs < hour) return `更新于 ${Math.max(1, Math.round(diffMs / minute))} 分钟前`;
|
|
if (diffMs < day) return `更新于 ${Math.round(diffMs / hour)} 小时前`;
|
|
return `更新于 ${Math.round(diffMs / day)} 天前`;
|
|
}
|
|
|
|
export function formatPrice(currency: string, value: number) {
|
|
if (value <= 0) return "免费";
|
|
return `${currency}${value}`;
|
|
}
|
|
|
|
export function formatDateTime(value?: string) {
|
|
if (!value) return "-";
|
|
const date = new Date(value);
|
|
if (Number.isNaN(date.getTime())) return "-";
|
|
return date.toLocaleString("zh-CN", { hour12: false });
|
|
}
|