fix(avatar): 移除并行工具轮播,头像固定显示当前工具,文字过渡与SVG切换同步
This commit is contained in:
parent
56c067b710
commit
4f940e9a86
@ -101,7 +101,6 @@ const props = withDefaults(
|
||||
}
|
||||
);
|
||||
const emit = defineEmits<{
|
||||
(event: 'active-index', index: number): void;
|
||||
(event: 'poke'): void;
|
||||
}>();
|
||||
|
||||
@ -314,18 +313,12 @@ function trackEyes() {
|
||||
trackRaf = requestAnimationFrame(trackEyes);
|
||||
}
|
||||
|
||||
// ---- 并行工具轮播 ----
|
||||
let carouselTimer: number | null = null;
|
||||
// ---- 工具 face 切换 ----
|
||||
let faceSwitchTimer: number | null = null;
|
||||
let blinkTimer: number | null = null;
|
||||
let nervousTimer: number | null = null;
|
||||
let isBlinking = false;
|
||||
let carouselIdx = 0;
|
||||
const internalMode = ref<string | null>(null);
|
||||
function stopCarousel() {
|
||||
if (carouselTimer) clearInterval(carouselTimer);
|
||||
carouselTimer = null;
|
||||
}
|
||||
function stopFaceSwitchTimer() {
|
||||
if (faceSwitchTimer) clearTimeout(faceSwitchTimer);
|
||||
faceSwitchTimer = null;
|
||||
@ -375,7 +368,6 @@ function triggerNervous() {
|
||||
stopAutoBlink();
|
||||
stopNervousTimer();
|
||||
stopTracking();
|
||||
stopCarousel();
|
||||
stopFaceSwitchTimer();
|
||||
activeFaceKey.value = null;
|
||||
sharedVisible.value = true;
|
||||
@ -424,20 +416,6 @@ function setIconFace(key: string, animated = true) {
|
||||
faceSwitchTimer = null;
|
||||
}, 160);
|
||||
}
|
||||
function startCarousel(keys: string[]) {
|
||||
stopCarousel();
|
||||
stopFaceSwitchTimer();
|
||||
carouselIdx = 0;
|
||||
setIconFace(keys[0]);
|
||||
emit('active-index', carouselIdx);
|
||||
if (keys.length < 2) return;
|
||||
carouselTimer = window.setInterval(() => {
|
||||
carouselIdx = (carouselIdx + 1) % keys.length;
|
||||
setIconFace(keys[carouselIdx]);
|
||||
emit('active-index', carouselIdx);
|
||||
}, 1450);
|
||||
}
|
||||
|
||||
// ---- 状态应用 ----
|
||||
function applyState() {
|
||||
if (props.mode !== 'idle' && internalMode.value) {
|
||||
@ -449,10 +427,11 @@ function applyState() {
|
||||
if (mode === 'tool') {
|
||||
stopTracking();
|
||||
const keys = (props.toolKeys || []).filter(Boolean);
|
||||
startCarousel(keys.length ? keys : ['command']);
|
||||
// 并行工具时固定显示第一个正在执行的工具;
|
||||
// 完成一个后 toolKeys 变化,自动切到下一个
|
||||
setIconFace(keys.length ? keys[0] : 'command');
|
||||
return;
|
||||
}
|
||||
stopCarousel();
|
||||
stopFaceSwitchTimer();
|
||||
if (mode === 'think') {
|
||||
stopTracking();
|
||||
@ -493,7 +472,13 @@ function applyState() {
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => [props.mode, props.toolKeys, props.tracking, internalMode.value], () => applyState(), { deep: true });
|
||||
// toolKeys 按内容 join 后再监听:avatarStatus computed 每次重算都产出新数组引用,
|
||||
// 若直接监听数组,流式期间(intent 打字、状态刷新)applyState 会被高频触发,
|
||||
// face 切换动画反复重启,表现为图标无规律抖动
|
||||
watch(
|
||||
() => [props.mode, (props.toolKeys || []).join('\u001f'), props.tracking, internalMode.value],
|
||||
() => applyState()
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化时直接定位,避免眼睛从 SVG 原点飞入
|
||||
@ -504,7 +489,6 @@ onMounted(() => {
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
stopTracking();
|
||||
stopCarousel();
|
||||
stopFaceSwitchTimer();
|
||||
stopAutoBlink();
|
||||
stopNervousTimer();
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-else-if="composerAvatarText"
|
||||
:key="`tool-${props.avatarStatus?.mode}`"
|
||||
:key="composerAvatarTextKey"
|
||||
class="composer-avatar__text"
|
||||
:class="{
|
||||
'composer-avatar__text--right': !floatingStatusVisible,
|
||||
@ -975,6 +975,15 @@ const composerAvatarText = computed(() => {
|
||||
return '';
|
||||
});
|
||||
|
||||
// key 跟随当前显示的工具(第一个 running tool)变化,
|
||||
// 工具1完成切到工具2时文字有 out-in 过渡,与 SVG 切换动画同步
|
||||
const composerAvatarTextKey = computed(() => {
|
||||
const s = props.avatarStatus;
|
||||
if (!s) return 'avatar-none';
|
||||
if (s.mode === 'tool') return `avatar-tool-${s.toolKeys?.[0] || ''}`;
|
||||
return `avatar-${s.mode}`;
|
||||
});
|
||||
|
||||
const projectGitMenuOpen = ref<null | 'project' | 'branch'>(null);
|
||||
|
||||
const closeProjectGitMenu = () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user