fix(chat): fold natal reports and drop homepage topic cards
Homepage no longer waits on /api/onboarding for six starter questions. Natal answers show the spoken layer first; the Level 2 skeleton sits in a collapsed 完整分析 block. Wide tables scroll sideways on a phone. Form inputs are 16px so iOS does not zoom on focus.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Split a chat answer into the spoken layer (before the first H2) and the
|
||||
* report skeleton (from that H2 onward). The cut is any ATX H2, so a drifted
|
||||
* first heading still folds instead of dumping the whole body.
|
||||
*
|
||||
* Fenced `##` lines are not cuts. The fence rule matches `chat-markdown-split`.
|
||||
*/
|
||||
|
||||
export type SpokenAndReportSplit = Readonly<{
|
||||
spoken: string;
|
||||
report: string;
|
||||
headings: readonly string[];
|
||||
}>;
|
||||
|
||||
const FENCE = /^\s{0,3}(`{3,}|~{3,})/;
|
||||
const H2 = /^##\s+\S/;
|
||||
|
||||
function extractHeadings(report: string): string[] {
|
||||
const lines = report.split("\n");
|
||||
let insideFence = false;
|
||||
const headings: string[] = [];
|
||||
for (const line of lines) {
|
||||
if (FENCE.test(line)) insideFence = !insideFence;
|
||||
if (!insideFence && H2.test(line)) {
|
||||
headings.push(line.replace(/^##\s+/, "").trim());
|
||||
}
|
||||
}
|
||||
return headings;
|
||||
}
|
||||
|
||||
export function splitSpokenAndReport(text: string): SpokenAndReportSplit {
|
||||
const lines = text.split("\n");
|
||||
let insideFence = false;
|
||||
let cut = -1;
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const line = lines[index] ?? "";
|
||||
if (FENCE.test(line)) insideFence = !insideFence;
|
||||
if (!insideFence && H2.test(line)) {
|
||||
cut = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cut < 0) return { spoken: text, report: "", headings: [] };
|
||||
const spoken = lines.slice(0, cut).join("\n").replace(/\s+$/u, "");
|
||||
const report = lines.slice(cut).join("\n");
|
||||
return { spoken, report, headings: extractHeadings(report) };
|
||||
}
|
||||
|
||||
export function shortenAnswerHeading(heading: string): string {
|
||||
if (heading === "统一参数与原始结构") return "统一参数";
|
||||
if (heading === "技法审计表") return "技法审计";
|
||||
return heading;
|
||||
}
|
||||
|
||||
export function answerDetailCaption(headings: readonly string[]): string {
|
||||
if (headings.length === 0) return "";
|
||||
const labels = headings.slice(0, 3).map(shortenAnswerHeading);
|
||||
if (headings.length <= 3) return labels.join("、");
|
||||
return `${labels.join("、")} 等 ${headings.length} 节`;
|
||||
}
|
||||
Reference in New Issue
Block a user