fix(welcome): 欢迎页沿用站点外观与 SEO 标题

合并 #683:欢迎页沿用站点外观与 SEO 标题
This commit is contained in:
Catlaxy AI
2026-10-06 09:23:18 +08:00
committed by GitHub
parent 19841cb9c5
commit 208da8d00d
3 changed files with 48 additions and 3 deletions

View File

@@ -7,8 +7,10 @@ import { isIsolatedPrevisRepro } from "@/lib/dev-repro";
installChunkRecovery();
// The public film entry checks its availability independently of workspace bootstrap.
if (/^\/welcome\/?$/.test(window.location.pathname)) void import("./welcome-application");
else {
if (/^\/welcome\/?$/.test(window.location.pathname)) {
void bootstrapAppearance().catch(() => undefined);
void import("./welcome-application");
} else {
// The backend-free DEV lab must not make requests before AppProviders isolates it.
const appearanceReady = isIsolatedPrevisRepro(import.meta.env.DEV, window.location.pathname) ? Promise.resolve() : bootstrapAppearance();
void import("./application");

View File

@@ -59,7 +59,6 @@ function WelcomeExperience({ look, brandName, onLookChange }: { look: WelcomeLoo
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
document.title = "影策 · 让一个故事从文字走向银幕";
const media = window.matchMedia("(prefers-reduced-motion: reduce)");
const onMotion = () => setReduced(media.matches);
media.addEventListener("change", onMotion);

View File

@@ -0,0 +1,44 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "node:test";
import vm from "node:vm";
const source = (path) => readFileSync(new URL(path, import.meta.url), "utf8");
test("welcome entry loads configured appearance", async () => {
let calls = 0;
const imports = [];
const main = source("../src/main.tsx")
.replace(/^import .*;\n/gm, "")
.replace(/import\.meta\.env\.DEV/g, "false")
.replace(/import\(/g, "loadModule(");
vm.runInNewContext(main, {
window: { location: { pathname: "/welcome" } },
installChunkRecovery() {},
isIsolatedDirectorRepro: () => false,
bootstrapAppearance: async () => { calls++; },
loadModule: async (name) => { imports.push(name); },
});
await Promise.resolve();
assert.equal(calls, 1, "welcome entry must bootstrap appearance");
assert.deepEqual(imports, ["./welcome-application"]);
});
test("welcome effects preserve configured SEO title", () => {
const page = source("../src/pages/welcome/index.tsx");
// Run the actual mount effects with inert motion/scroll listeners.
const effects = [...page.matchAll(/useEffect\(\(\) => \{([\s\S]*?)\n \}, \[([^\]]*)\]\);/g)].filter((match) => match[2] === "");
assert.ok(effects.length > 0);
for (const title of ["Custom SEO Title", "Custom Site Name"]) {
const document = { title };
for (const [, body] of effects) {
vm.runInNewContext(`(() => {${body}\n})()`, {
document,
window: { matchMedia: () => ({ matches: false, addEventListener() {}, removeEventListener() {} }), addEventListener() {}, removeEventListener() {} },
storyRef: { current: null }, restorePickerFocus: { current: false },
setReduced() {}, setLook() {}, getWelcomeLook() {},
});
}
assert.equal(document.title, title, "welcome must preserve appearance metadata title");
}
});