perf: isolate lovart home route
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-04-30 00:41:37 +08:00
parent dedc62cb79
commit 77a32a4d60
2 changed files with 133 additions and 118 deletions

110
app/(chat)/classic/page.tsx Normal file
View File

@ -0,0 +1,110 @@
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { Suspense } from "react";
import { ClassicChatStart } from "@/components/classic-chat-start";
import { isVideoModelDescriptor } from "@/lib/ai/model-classification";
import { isAiModelAgentAuto } from "@/lib/db/ai-model-flags";
import {
getDefaultAiModel,
getEnabledAiModelsWithProvider,
getUserById,
} from "@/lib/db/queries";
import { generateUUID } from "@/lib/utils";
import { auth } from "../../(auth)/auth";
function isNanoBananaProModel(model: {
displayName?: string | null;
modelId?: string | null;
}) {
const displayName = String(model.displayName || "").toLowerCase();
const modelId = String(model.modelId || "").toLowerCase();
return (
displayName.includes("nano banana pro") ||
displayName.includes("nano-banana-pro") ||
modelId.includes("nano-banana-pro") ||
modelId.includes("nano_banana_pro") ||
modelId.includes("nano-banana")
);
}
export default function ClassicPage() {
return (
<Suspense fallback={<div className="flex h-dvh" />}>
<ClassicChatPage />
</Suspense>
);
}
async function ClassicChatPage() {
const id = generateUUID();
const [session, cookieStore] = await Promise.all([auth(), cookies()]);
if (!session?.user) {
redirect("/login");
}
const modelIdFromCookie = cookieStore.get("chat-model");
let initialModelId = modelIdFromCookie?.value;
const currentUser = session.user.id
? await getUserById({ id: session.user.id }).catch(() => undefined)
: undefined;
const allowHiddenModels =
session.user.type === "admin" || Boolean(currentUser?.isHighVip);
const defaultModel = await getDefaultAiModel();
const enabledModels = await getEnabledAiModelsWithProvider(false, true);
const visibleModels = enabledModels.filter(
({ model }) =>
!isAiModelAgentAuto(model) && (allowHiddenModels || !model.isHidden)
);
const preferredImageModels = visibleModels.filter(
({ model, provider }) =>
model.supportsImageGen &&
!isVideoModelDescriptor({
providerType: provider.type,
modelId: model.modelId,
capabilities: model.capabilities,
supportsImageGen: model.supportsImageGen,
})
);
const nanoBananaModel = preferredImageModels.find(({ model }) =>
isNanoBananaProModel(model)
);
const cookieModel = initialModelId
? visibleModels.find(({ model }) => model.id === initialModelId)
: undefined;
if (!initialModelId || !cookieModel) {
if (nanoBananaModel) {
initialModelId = nanoBananaModel.model.id;
} else if (
defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
(allowHiddenModels || !defaultModel.isHidden) &&
preferredImageModels.some(({ model }) => model.id === defaultModel.id)
) {
initialModelId = defaultModel.id;
} else if (preferredImageModels.length > 0) {
const preferredDefaultImageModel = preferredImageModels.find(
({ model }) => model.isDefault
);
initialModelId = (preferredDefaultImageModel || preferredImageModels[0])
.model.id;
} else if (
defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
(allowHiddenModels || !defaultModel.isHidden)
) {
initialModelId = defaultModel.id;
} else if (visibleModels.length > 0) {
initialModelId = visibleModels[0].model.id;
}
}
return (
<ClassicChatStart
id={id}
initialModelId={initialModelId || ""}
userType={session.user.type}
/>
);
}

View File

@ -1,30 +1,11 @@
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { Suspense } from "react";
import { LovartHome } from "@/components/home/lovart-home";
import { generateUUID } from "@/lib/utils";
import { auth } from "../(auth)/auth";
import {
getDefaultAiModel,
getEnabledAiModelsWithProvider,
getUserById,
getSiteSettings,
getSystemSetting,
} from "@/lib/db/queries";
import { isAiModelAgentAuto } from "@/lib/db/ai-model-flags";
import { isVideoModelDescriptor } from "@/lib/ai/model-classification";
function isNanoBananaProModel(model: { displayName?: string | null; modelId?: string | null }) {
const displayName = String(model.displayName || "").toLowerCase();
const modelId = String(model.modelId || "").toLowerCase();
return (
displayName.includes("nano banana pro") ||
displayName.includes("nano-banana-pro") ||
modelId.includes("nano-banana-pro") ||
modelId.includes("nano_banana_pro") ||
modelId.includes("nano-banana")
);
}
export default function Page() {
return (
@ -35,12 +16,9 @@ export default function Page() {
}
async function NewChatPage() {
const id = generateUUID();
const [session, cookieStore, siteSettings, homeVariantSetting, surpriseCategoriesSetting] =
const [session, siteSettings, homeVariantSetting, surpriseCategoriesSetting] =
await Promise.all([
auth(),
cookies(),
getSiteSettings(),
getSystemSetting({ key: "home_variant" }).catch(() => undefined),
getSystemSetting({ key: "home_surprise_categories" }).catch(() => undefined),
@ -53,104 +31,31 @@ async function NewChatPage() {
.filter(Boolean)
: ["全部", "精选"];
if (!session?.user && homeVariant !== "lovart") {
redirect("/login");
if (homeVariant !== "lovart") {
redirect("/classic");
}
if (homeVariant === "lovart") {
return (
<LovartHome
user={
session?.user
? {
id: session.user.id,
email: session.user.email,
name: session.user.name,
type: session.user.type,
}
: null
}
isAuthenticated={Boolean(session?.user && session.user.type !== "guest")}
siteName={siteSettings.siteName || "AI Chatbot"}
siteLogo={siteSettings.siteLogo || ""}
siteLogoDark={siteSettings.siteLogoDark || ""}
surpriseCategories={surpriseCategories}
heroPromoText={siteSettings.lovartPromoText}
heroPromoActionText={siteSettings.lovartPromoActionText}
heroTitleText={siteSettings.lovartHeroTitle}
heroSubtitleText={siteSettings.lovartHeroSubtitle}
/>
);
}
const modelIdFromCookie = cookieStore.get("chat-model");
let initialModelId = modelIdFromCookie?.value;
const currentUser = session?.user?.id
? await getUserById({ id: session.user.id }).catch(() => undefined)
: undefined;
const allowHiddenModels =
session?.user?.type === "admin" || Boolean(currentUser?.isHighVip);
const defaultModel = await getDefaultAiModel();
const enabledModels = await getEnabledAiModelsWithProvider(false, true);
const visibleModels = enabledModels.filter(
({ model }) =>
!isAiModelAgentAuto(model) &&
(allowHiddenModels || !model.isHidden)
);
const preferredImageModels = visibleModels.filter(
({ model, provider }) =>
model.supportsImageGen &&
!isVideoModelDescriptor({
providerType: provider.type,
modelId: model.modelId,
capabilities: model.capabilities,
supportsImageGen: model.supportsImageGen,
})
);
const nanoBananaModel = preferredImageModels.find(({ model }) =>
isNanoBananaProModel(model)
);
const cookieModel = initialModelId
? visibleModels.find(({ model }) => model.id === initialModelId)
: undefined;
if (
!initialModelId ||
!cookieModel
) {
if (nanoBananaModel) {
initialModelId = nanoBananaModel.model.id;
} else if (
defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
(allowHiddenModels || !defaultModel.isHidden) &&
preferredImageModels.some(({ model }) => model.id === defaultModel.id)
) {
initialModelId = defaultModel.id;
} else if (preferredImageModels.length > 0) {
const preferredDefaultImageModel = preferredImageModels.find(
({ model }) => model.isDefault
);
initialModelId = (preferredDefaultImageModel || preferredImageModels[0]).model.id;
} else if (
defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
(allowHiddenModels || !defaultModel.isHidden)
) {
initialModelId = defaultModel.id;
} else if (visibleModels.length > 0) {
initialModelId = visibleModels[0].model.id;
}
}
const { ClassicChatStart } = await import("@/components/classic-chat-start");
return (
<ClassicChatStart
id={id}
initialModelId={initialModelId || ""}
userType={session?.user?.type}
<LovartHome
user={
session?.user
? {
id: session.user.id,
email: session.user.email,
name: session.user.name,
type: session.user.type,
}
: null
}
isAuthenticated={Boolean(session?.user && session.user.type !== "guest")}
siteName={siteSettings.siteName || "AI Chatbot"}
siteLogo={siteSettings.siteLogo || ""}
siteLogoDark={siteSettings.siteLogoDark || ""}
surpriseCategories={surpriseCategories}
heroPromoText={siteSettings.lovartPromoText}
heroPromoActionText={siteSettings.lovartPromoActionText}
heroTitleText={siteSettings.lovartHeroTitle}
heroSubtitleText={siteSettings.lovartHeroSubtitle}
/>
);
}