私密/公开互斥兜底 + 智能体搜索按显示后名称匹配 + 多处小修

- 后端 update_agent / set_agent_private 增加兜底:is_private=true 时强制
  published=false,杜绝同时落在公开+私密两个广场的灰色态
- agent-card 编辑弹窗暴露 editIsPrivate 开关,与公开发布开关在前端互斥校验
- agent-gallery 智能体模糊搜索改为前端针对 desensitize() 后的名字比对,
  解决脱敏显示与原始名字不一致导致看似搜索失效的问题
- useUpdateAgent 在 onSuccess 立刻把新数据 patch 进所有 ["agents"] 列表
  缓存,卡片在后台 refetch 完成前先行 re-render,避免「切换私密/发布后
  好像没反应」的体感延迟
- useGlobalShortcuts 对 event.key 为 undefined(IME 合成 / 扩展注入)做
  容错,否则会抛 TypeError 把后续所有快捷键吃掉

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
吉鑫升andClaude Opus 4.7 authored and xuhd committed 2026-05-28 18:28:49 +08:00
1 parent ae3e2fb4e8
commit 83714f628b
5 files changed
+130 -24

No files matched your search

+25 -4
View File
@@ -17,7 +17,25 @@ import {
setAgentPrivate,
updateAgent,
} from "./api";
import type { CreateAgentRequest, UpdateAgentRequest } from "./types";
import type { Agent, CreateAgentRequest, UpdateAgentRequest } from "./types";
/** Patch an updated agent into every cached agent listing immediately so
* cards re-render before the background refetch finishes. Without this the
* mutation just invalidates the query and the user has to wait for the
* round-trip + render — which on a big list feels like nothing happened.
*/
function applyAgentToCache(
queryClient: ReturnType<typeof useQueryClient>,
next: Agent,
) {
queryClient.setQueriesData<Agent[] | undefined>(
{ queryKey: ["agents"] },
(old) => {
if (!Array.isArray(old)) return old;
return old.map((a) => (a.id === next.id ? { ...a, ...next } : a));
},
);
}
export function useAgents(params: { search?: string; tagIds?: string[] } = {}) {
const search = params.search ?? "";
@@ -59,7 +77,8 @@ export function useUpdateAgent() {
id: string;
request: UpdateAgentRequest;
}) => updateAgent(id, request),
onSuccess: (_data, { id }) => {
onSuccess: (data, { id }) => {
applyAgentToCache(queryClient, data);
void queryClient.invalidateQueries({ queryKey: ["agents"] });
void queryClient.invalidateQueries({ queryKey: ["agents", id] });
},
@@ -98,7 +117,8 @@ export function useSetAgentFeatured() {
return useMutation({
mutationFn: ({ id, order }: { id: string; order: number | null }) =>
setAgentFeatured(id, order),
onSuccess: (_data, { id }) => {
onSuccess: (data, { id }) => {
applyAgentToCache(queryClient, data);
invalidateAgentQueries(queryClient);
void queryClient.invalidateQueries({ queryKey: ["agents", id] });
},
@@ -134,7 +154,8 @@ export function useSetAgentPrivate() {
return useMutation({
mutationFn: ({ id, isPrivate }: { id: string; isPrivate: boolean }) =>
setAgentPrivate(id, isPrivate),
onSuccess: (_data, { id }) => {
onSuccess: (data, { id }) => {
applyAgentToCache(queryClient, data);
invalidateAgentQueries(queryClient);
void queryClient.invalidateQueries({ queryKey: ["agents", id] });
void queryClient.invalidateQueries({