Repository navigation
Expand file tree
/
Copy pathInputFooter.tsx
More file actions
102 lines (92 loc) · 3.73 KB
/
Copy pathInputFooter.tsx
File metadata and controls
102 lines (92 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { memo, useSyncExternalStore } from 'react'
import { useTranslation } from 'react-i18next'
import type { RefObject } from 'react'
import { FastForwardIcon } from '../../../components/Icons'
import { autoApproveStore, type FullAutoMode } from '../../../store/autoApproveStore'
// ============================================
// Full Auto 状态 hook
// ============================================
function useFullAutoMode(paneId: string): FullAutoMode {
return useSyncExternalStore(
cb => autoApproveStore.onFullAutoChange(cb),
() => autoApproveStore.getPaneFullAutoMode(paneId),
)
}
// ============================================
// InputFooter - disclaimer + full auto toggle
//
// v2 移除了 todo 能力(连 "todo" 字符串都不存在),因此这里原本的
// todo 进度环、任务列表与悬浮面板一并删除,只保留免责声明与
// Full Auto 三态开关。
// ============================================
interface InputFooterProps {
paneId: string
sessionId?: string | null
onNewChat?: () => void
inputContainerRef?: RefObject<HTMLDivElement | null>
/** 阻塞中的后台任务(非空时显示「移到后台」入口,官方 BackgroundMoveHint 同款克制呈现) */
backgroundTasks?: Array<{ label: string }>
onMoveToBackground?: () => void
backgroundMoving?: boolean
}
export const InputFooter = memo(function InputFooter({
paneId,
onNewChat,
backgroundTasks,
onMoveToBackground,
backgroundMoving,
}: InputFooterProps) {
const { t } = useTranslation(['chat', 'common'])
const fullAutoMode = useFullAutoMode(paneId)
const hasBlocking = Boolean(backgroundTasks && backgroundTasks.length > 0 && onMoveToBackground)
return (
<div className="relative flex h-full w-full items-center justify-center gap-2 text-[length:var(--fs-xs)] leading-none text-text-500">
{/* Full Auto 三态切换: off -> session -> global -> off */}
<button
onClick={() => autoApproveStore.cyclePaneFullAutoMode(paneId)}
className="shrink-0 flex items-center justify-center hover:text-text-300 transition-colors"
title={
fullAutoMode === 'off'
? t('inputFooter.autoApproveOff')
: fullAutoMode === 'session'
? t('inputFooter.autoApproveSession')
: t('inputFooter.autoApproveGlobal')
}
>
<FastForwardIcon
size={11}
className={`transition-colors ${
fullAutoMode === 'global'
? 'text-danger-100 drop-shadow-[0_0_4px_var(--color-danger-100)]'
: fullAutoMode === 'session'
? 'text-warning-100 drop-shadow-[0_0_4px_var(--color-warning-100)]'
: ''
}`}
/>
</button>
<span className="text-text-500/30 shrink-0">·</span>
{/* disclaimer / 移到后台(v1 todos 的布局同款:
平时只有免责声明;有阻塞任务时换成任务入口 + 新对话) */}
{!hasBlocking ? (
<button onClick={onNewChat} className="hover:text-text-300 transition-colors">
{t('inputFooter.pleaseVerify')}
</button>
) : (
<>
<button
onClick={onMoveToBackground}
disabled={backgroundMoving}
className="hover:text-text-300 transition-colors disabled:opacity-50"
title={(backgroundTasks ?? []).map(task => task.label).join('、')}
>
{t('chat:sessionBackground.move', { count: backgroundTasks?.length ?? 0 })}
</button>
<span className="text-text-500/30 shrink-0">·</span>
<button onClick={onNewChat} className="hover:text-text-300 transition-colors shrink-0">
{t('sidebar.newChat')}
</button>
</>
)}
</div>
)
})