Merge branch 'master' into feat/home-saas-premium-and-icon-system

This commit is contained in:
2026-06-10 02:22:32 +00:00
58 changed files with 3461 additions and 265 deletions
+29 -2
View File
@@ -8,6 +8,7 @@ import ToastContainer from "./components/toast/ToastContainer";
import { toast } from "./components/toast/toastStore";
import { aiGenerationClient } from "./api/aiGenerationClient";
import { keyServerClient } from "./api/keyServerClient";
import { setUserMaxConcurrency } from "./api/generationConcurrency";
import { notificationClient } from "./api/notificationClient";
import {
SERVER_SESSION_REPLACED_EVENT,
@@ -32,6 +33,7 @@ const CharacterMixPage = lazy(() => import("./features/character-mix/CharacterMi
const CommunityPage = lazy(() => import("./features/community/CommunityPage"));
const CommunityCaseAddPage = lazy(() => import("./features/community-review/CommunityCaseAddPage"));
const CommunityReviewPage = lazy(() => import("./features/community-review/CommunityReviewPage"));
const BetaApplicationsPage = lazy(() => import("./features/beta-applications/BetaApplicationsPage"));
const AvatarConsolePage = lazy(() => import("./features/digital-human/AvatarConsolePage"));
const DigitalHumanPage = lazy(() => import("./features/digital-human/DigitalHumanPage"));
const DialogGeneratorPage = lazy(() => import("./features/dialog-generator/DialogGeneratorPage"));
@@ -108,6 +110,7 @@ const VIEW_KEYS = new Set<WebViewKey>([
"more",
"communityReview",
"communityCaseAdd",
"betaApplications",
"report",
"providerHealth",
"userAgreement",
@@ -123,6 +126,7 @@ const LEGACY_PAGE_STYLE_VIEWS = new Set<WebViewKey>([
"community",
"communityReview",
"communityCaseAdd",
"betaApplications",
"assets",
"ecommerce",
"ecommerceHub",
@@ -169,6 +173,8 @@ function normalizeViewKey(rawView: string): WebViewKey {
? "communityReview"
: rawView === "community-case-add"
? "communityCaseAdd"
: rawView === "beta-applications" || rawView === "beta-application-review"
? "betaApplications"
: rawView;
return VIEW_KEYS.has(normalized as WebViewKey) ? (normalized as WebViewKey) : "not-found";
}
@@ -211,7 +217,7 @@ function createWorkflowFromResult(payload: WorkbenchResultActionPayload): WebCan
description: payload.prompt || "从生成结果进入画布继续创作。",
source: "blank",
settings: {
model: payload.resultType === "video" ? "Seedance 2.0" : "Nano Banana Pro",
model: payload.resultType === "video" ? "Seedance 2.0" : "omni-水果 Pro",
ratio: payload.resultType === "video" ? "16:9" : "1:1",
duration: payload.resultType === "video" ? "6s" : "0s",
resolution: payload.resultType === "video" ? "720p" : "2K",
@@ -382,6 +388,7 @@ function App() {
const [ecommerceEverMounted, setEcommerceEverMounted] = useState(false);
const [workbenchResetToken, setWorkbenchResetToken] = useState(0);
const [onboardingActive, setOnboardingActive] = useState(false);
const isEcommerceActive = activeView === "ecommerce" || activeView === "ecommerceHub";
useEffect(() => {
if (isEcommerceActive && !ecommerceEverMounted) setEcommerceEverMounted(true);
@@ -483,9 +490,21 @@ function App() {
}
}, [session, setView, setWorkspaceExpanded]);
const handleStartOnboarding = useCallback(() => {
setOnboardingActive(true);
try { window.localStorage.setItem("omniai:onboarding", "1"); } catch {}
handleSetView("workbench");
}, [handleSetView]);
const handleEndOnboarding = useCallback(() => {
setOnboardingActive(false);
try { window.localStorage.removeItem("omniai:onboarding"); } catch {}
}, []);
const clearAuthenticatedState = useCallback((options?: { resetView?: boolean }) => {
clearAllUserStorage();
clearSessionState();
setUserMaxConcurrency(null);
setProjects([]);
setProjectsLoaded(true);
setUsage(emptyUsageSummary);
@@ -594,6 +613,7 @@ function App() {
const nextSession = await keyServerClient.getCurrentSession();
if (cancelled) return;
setSession(nextSession);
setUserMaxConcurrency(nextSession?.user?.maxConcurrency);
await hydrateAccountData(nextSession);
};
@@ -626,6 +646,7 @@ function App() {
if (cancelled) return;
if (nextSession) {
setSession(nextSession);
setUserMaxConcurrency(nextSession?.user?.maxConcurrency);
} else {
clearAuthenticatedState({ resetView: true });
}
@@ -963,6 +984,7 @@ function App() {
async (nextSession: WebUserSession) => {
hideSessionReplaced();
setSession(nextSession);
setUserMaxConcurrency(nextSession?.user?.maxConcurrency);
await hydrateAccountData(nextSession);
if (nextSession.user.email && !nextSession.user.emailVerified) {
@@ -1026,7 +1048,7 @@ function App() {
previewUrl: payload.resultUrl,
params: payload.resultType === "video"
? { model: "Kling V3 Omni", aspectRatio: "16:9", resolution: "720p", duration: "6s", videoMode: "text-to-video" }
: { model: "Nano Banana Pro", aspectRatio: "1:1", imageSize: "2K" },
: { model: "omni-水果 Pro", aspectRatio: "1:1", imageSize: "2K" },
assetRef: payload.resultOssKey ? { url: payload.resultUrl, ossKey: payload.resultOssKey, mediaType: payload.resultType === "video" ? "video/mp4" : "image/png", sourceTaskId: payload.taskId } : undefined,
},
];
@@ -1318,12 +1340,16 @@ function App() {
onOpenReview={() => handleSetView("communityReview")}
/>
);
case "betaApplications":
return <BetaApplicationsPage session={session} onOpenLogin={handleOpenLogin} />;
case "workbench":
return (
<WorkbenchPage
key={`workbench-${workbenchResetToken}`}
isAuthenticated={Boolean(session)}
session={session}
onboarding={onboardingActive}
onEndOnboarding={handleEndOnboarding}
onRequireLogin={handleRequireTaskLogin}
onOpenResultInCanvas={handleOpenResultInCanvas}
onRefreshUsage={refreshUsage}
@@ -1334,6 +1360,7 @@ function App() {
return (
<HomePage
onOpenGenerate={() => handleSetView("workbench")}
onStartOnboarding={handleStartOnboarding}
onOpenCanvas={() => handleSetView("canvas")}
onOpenEcommerce={() => handleSetView("ecommerce")}
onOpenScriptReview={() => handleSetView("scriptTokens")}