fix(chat): honor new-chat intent from secondary pages
Create a fresh local consultation for explicit new-chat navigation and keep reserved recovery from taking over its landing. Add regression tests and record validation gaps for remote review. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1062,6 +1062,7 @@ export default function Home() {
|
||||
setStartGreeting(nextProfile.name.trim() ? createStartGreeting(nextProfile.name) : "");
|
||||
setOnboardingStep(missingProfileStep(nextProfile) ?? "name");
|
||||
setSessions(nextSessions);
|
||||
if (bootstrapSelection.urlAction === "new-chat") writeSessionUrl(null, "replace");
|
||||
setActiveSessionId(landingSessionId);
|
||||
if (bootstrapSelection.clearStoredReturn) clearLoginSessionReturn();
|
||||
if (bootstrapSelection.urlAction === "replace-clear") writeSessionUrl(null, "replace");
|
||||
@@ -1074,6 +1075,10 @@ export default function Home() {
|
||||
if (reservedConsultation?.status === "reserved") {
|
||||
const recoverySession = nextSessions.find((session) => session.id === reservedConsultation.sessionId);
|
||||
if (recoverySession) restoreConsultationRecovery(recoverySession, reservedConsultation.requestId, storedPending);
|
||||
if (bootstrapSelection.urlAction === "new-chat") {
|
||||
setActiveSessionId(landingSessionId);
|
||||
setComposerNotice("");
|
||||
}
|
||||
}
|
||||
if (modelCatalogResult.unavailable) {
|
||||
setComposerNotice("模型服务暂时不可用,当前无法发送问题。");
|
||||
|
||||
@@ -19,7 +19,7 @@ import { usePathname } from "next/navigation";
|
||||
import { useEffect, useRef } from "react";
|
||||
import type { Ref } from "react";
|
||||
import { AppLink } from "@/components/app-link";
|
||||
import { persistLoginSessionReturn, sessionHref } from "@/lib/chat-session-url";
|
||||
import { newChatHref, persistLoginSessionReturn, sessionHref } from "@/lib/chat-session-url";
|
||||
import { prefetchSecondaryPage } from "@/lib/secondary-page-data";
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -248,7 +248,7 @@ export function AppSidebar({
|
||||
{showExpandedContent ? <span>{creatingSession ? "正在创建" : "新建对话"}</span> : null}
|
||||
</SidebarMenuButton>
|
||||
) : (
|
||||
<SidebarMenuLink className="new-chat" tooltip="新对话" href="/" onClick={closeDrawer}>
|
||||
<SidebarMenuLink className="new-chat" tooltip="新对话" href={newChatHref()} onClick={closeDrawer}>
|
||||
<SquarePen size={18} strokeWidth={1.75} aria-hidden="true" />
|
||||
{showExpandedContent ? <span>新建对话</span> : null}
|
||||
</SidebarMenuLink>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export const SESSION_URL_QUERY_KEY = "c";
|
||||
export const NEW_CHAT_QUERY_KEY = "new";
|
||||
export const SESSION_URL_RETURN_STORAGE_KEY = "jyotisha.session-url-return";
|
||||
export const SESSION_MISSING_NOTICE = "该对话不存在或已被删除";
|
||||
export const SESSION_LOOKUP_FAILED_NOTICE = "这条对话暂时读不到,请稍后重试。";
|
||||
@@ -11,11 +12,20 @@ export type SessionUrlQuery = {
|
||||
|
||||
export type BootstrapSessionSelection = {
|
||||
readonly sessionId: string;
|
||||
readonly urlAction: "keep" | "replace-selected" | "replace-clear" | "none" | "lookup";
|
||||
readonly urlAction: "keep" | "replace-selected" | "replace-clear" | "none" | "lookup" | "new-chat";
|
||||
readonly missing: boolean;
|
||||
readonly clearStoredReturn: boolean;
|
||||
};
|
||||
|
||||
export function newChatHref(): string {
|
||||
return "/?new=1";
|
||||
}
|
||||
|
||||
export function parseNewChatIntent(search: string): boolean {
|
||||
const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
||||
return params.has(NEW_CHAT_QUERY_KEY);
|
||||
}
|
||||
|
||||
export function parseSessionUrlQuery(search: string): SessionUrlQuery {
|
||||
const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
||||
if (!params.has(SESSION_URL_QUERY_KEY)) {
|
||||
@@ -30,6 +40,7 @@ export function parseSessionUrlQuery(search: string): SessionUrlQuery {
|
||||
|
||||
export function sessionHref(search: string, sessionId: string | null, pathname = "/"): string {
|
||||
const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
||||
params.delete(NEW_CHAT_QUERY_KEY);
|
||||
if (sessionId) params.set(SESSION_URL_QUERY_KEY, sessionId);
|
||||
else params.delete(SESSION_URL_QUERY_KEY);
|
||||
const query = params.toString();
|
||||
@@ -79,6 +90,14 @@ export function resolveBootstrapSessionSelection(input: {
|
||||
readonly search: string;
|
||||
readonly storedReturnId: string | null;
|
||||
}): BootstrapSessionSelection {
|
||||
if (parseNewChatIntent(input.search)) {
|
||||
return {
|
||||
sessionId: input.defaultSessionId,
|
||||
urlAction: "new-chat",
|
||||
missing: false,
|
||||
clearStoredReturn: true,
|
||||
};
|
||||
}
|
||||
const query = parseSessionUrlQuery(input.search);
|
||||
if (query.present) {
|
||||
if (query.sessionId && input.listedIds.includes(query.sessionId)) {
|
||||
|
||||
@@ -18,7 +18,7 @@ export type LandingSession = Readonly<{
|
||||
messages: readonly unknown[];
|
||||
}>;
|
||||
|
||||
export type LandingUrlAction = "keep" | "replace-selected" | "replace-clear" | "none" | "lookup";
|
||||
export type LandingUrlAction = "keep" | "replace-selected" | "replace-clear" | "none" | "lookup" | "new-chat";
|
||||
|
||||
/**
|
||||
* A rectification Case is opened only when the address bar names that session
|
||||
@@ -43,7 +43,7 @@ export function resolveStarterHomeLandingSessionId(
|
||||
selectedId: string,
|
||||
urlAction: LandingUrlAction,
|
||||
): string {
|
||||
if (urlAction === "keep" || urlAction === "replace-selected" || urlAction === "lookup") {
|
||||
if (urlAction === "keep" || urlAction === "replace-selected" || urlAction === "lookup" || urlAction === "new-chat") {
|
||||
return selectedId;
|
||||
}
|
||||
const selected = sessions.find((session) => session.id === selectedId);
|
||||
@@ -61,6 +61,7 @@ export function starterHomeLandingNeedsConsultation(
|
||||
landingId: string,
|
||||
urlAction: LandingUrlAction,
|
||||
): boolean {
|
||||
if (urlAction === "new-chat") return true;
|
||||
if (urlAction === "keep" || urlAction === "replace-selected" || urlAction === "lookup") return false;
|
||||
const landing = sessions.find((session) => session.id === landingId);
|
||||
return !landing || landing.sessionType === "birth_time_rectification";
|
||||
|
||||
Reference in New Issue
Block a user