fix(input-composer): 调整AI形象与git状态栏的对齐、间距及文字定位

This commit is contained in:
JOJO 2026-07-10 04:17:39 +08:00
parent cb70bc2929
commit d2170567e6

View File

@ -89,7 +89,7 @@
:mode="props.avatarStatus.mode" :mode="props.avatarStatus.mode"
:tool-keys="props.avatarStatus.toolKeys || []" :tool-keys="props.avatarStatus.toolKeys || []"
:tracking="props.avatarStatus.tracking !== false" :tracking="props.avatarStatus.tracking !== false"
:size="40" :size="45"
hex-background hex-background
/> />
<Transition name="composer-avatar-text-fade" mode="out-in"> <Transition name="composer-avatar-text-fade" mode="out-in">
@ -119,85 +119,87 @@
</div> </div>
</transition> </transition>
<transition name="floating-status-motion"> <transition name="floating-status-motion">
<div v-if="floatingStatusVisible" class="floating-project-status" @click.stop> <div v-if="floatingStatusVisible" class="floating-status-row" @click.stop>
<span v-if="projectGitSummaryForRender" class="floating-project-status__left"> <div class="floating-project-status" @click.stop>
<span class="floating-project-status__menu-wrap"> <span v-if="projectGitSummaryForRender" class="floating-project-status__left">
<button <span class="floating-project-status__menu-wrap">
type="button" <button
class="floating-project-status__button floating-project-status__button--project" type="button"
:class="{ class="floating-project-status__button floating-project-status__button--project"
'floating-project-status__button--active': projectGitMenuOpen === 'project' :class="{
}" 'floating-project-status__button--active': projectGitMenuOpen === 'project'
@click.stop="toggleProjectGitMenu('project')" }"
> @click.stop="toggleProjectGitMenu('project')"
{{ projectGitSummaryForRender.projectName }} >
</button> {{ projectGitSummaryForRender.projectName }}
<div
v-if="projectGitMenuOpen === 'project'"
class="floating-project-status__submenu floating-project-status__submenu--project"
@click.stop
>
<button type="button" @click.stop="openProjectInFileManager">
在文件管理器中打开
</button> </button>
<button type="button" @click.stop="copyProjectPath">复制地址</button> <div
</div> v-if="projectGitMenuOpen === 'project'"
class="floating-project-status__submenu floating-project-status__submenu--project"
@click.stop
>
<button type="button" @click.stop="openProjectInFileManager">
在文件管理器中打开
</button>
<button type="button" @click.stop="copyProjectPath">复制地址</button>
</div>
</span>
<span class="floating-project-status__menu-wrap">
<button
type="button"
class="floating-project-status__button floating-project-status__button--branch"
:class="{
'floating-project-status__button--active': projectGitMenuOpen === 'branch'
}"
@click.stop="toggleProjectGitMenu('branch')"
>
{{ projectGitSummaryForRender.branch }}
</button>
<div
v-if="projectGitMenuOpen === 'branch'"
class="floating-project-status__submenu floating-project-status__submenu--branch"
@click.stop
>
<button type="button" @click.stop="copyProjectBranch">复制分支名称</button>
</div>
</span>
</span> </span>
<span class="floating-project-status__menu-wrap"> <span class="floating-project-status__right">
<span v-if="goalRunning" class="floating-project-status__notice">目标模式运行中</span>
<span v-else-if="goalModeArmed" class="floating-project-status__notice"
>目标模式就绪</span
>
<button <button
v-if="userQuestionMinimized && pendingUserQuestionCount > 0"
type="button" type="button"
class="floating-project-status__button floating-project-status__button--branch" class="floating-project-status__notice floating-project-status__notice--button"
:class="{ @click.stop="$emit('restore-user-question')"
'floating-project-status__button--active': projectGitMenuOpen === 'branch'
}"
@click.stop="toggleProjectGitMenu('branch')"
> >
{{ projectGitSummaryForRender.branch }} 等待回答问题
</button> </button>
<div <button
v-if="projectGitMenuOpen === 'branch'" v-if="terminalCount > 0"
class="floating-project-status__submenu floating-project-status__submenu--branch" type="button"
@click.stop class="floating-project-status__terminal"
@click.stop="$emit('realtime-terminal')"
> >
<button type="button" @click.stop="copyProjectBranch">复制分支名称</button> {{ terminalCount }} 个终端
</div> </button>
<button
v-if="projectGitSummaryForRender"
type="button"
class="floating-project-status__stats"
@click.stop="$emit('open-git-changes-panel')"
>
<span class="floating-project-status__add"
>+<RollingNumber :value="projectGitSummaryForRender.additions"
/></span>
<span class="floating-project-status__del"
>-<RollingNumber :value="projectGitSummaryForRender.deletions"
/></span>
</button>
</span> </span>
</span> </div>
<span class="floating-project-status__right">
<span v-if="goalRunning" class="floating-project-status__notice">目标模式运行中</span>
<span v-else-if="goalModeArmed" class="floating-project-status__notice"
>目标模式就绪</span
>
<button
v-if="userQuestionMinimized && pendingUserQuestionCount > 0"
type="button"
class="floating-project-status__notice floating-project-status__notice--button"
@click.stop="$emit('restore-user-question')"
>
等待回答问题
</button>
<button
v-if="terminalCount > 0"
type="button"
class="floating-project-status__terminal"
@click.stop="$emit('realtime-terminal')"
>
{{ terminalCount }} 个终端
</button>
<button
v-if="projectGitSummaryForRender"
type="button"
class="floating-project-status__stats"
@click.stop="$emit('open-git-changes-panel')"
>
<span class="floating-project-status__add"
>+<RollingNumber :value="projectGitSummaryForRender.additions"
/></span>
<span class="floating-project-status__del"
>-<RollingNumber :value="projectGitSummaryForRender.deletions"
/></span>
</button>
</span>
</div> </div>
</transition> </transition>
<div <div
@ -2484,13 +2486,13 @@ const collectComposerVisualHeight = () => {
// //
// .goal-mode-banner--collapsed // .goal-mode-banner--collapsed
const nodes = root.querySelectorAll( const nodes = root.querySelectorAll(
'.runtime-queue-list:not(.runtime-queue-list--empty), .floating-project-status, .composer-avatar' '.runtime-queue-list:not(.runtime-queue-list--empty), .floating-status-row, .composer-avatar'
); );
nodes.forEach((node) => { nodes.forEach((node) => {
if (!(node instanceof HTMLElement)) return; if (!(node instanceof HTMLElement)) return;
// floatingStatusVisible / showComposerAvatar false DOM 退 // floatingStatusVisible / showComposerAvatar false DOM 退
// 退 // 退
if (node.classList.contains('floating-project-status') && !floatingStatusVisible.value) return; if (node.classList.contains('floating-status-row') && !floatingStatusVisible.value) return;
if (node.classList.contains('composer-avatar') && !showComposerAvatar.value) return; if (node.classList.contains('composer-avatar') && !showComposerAvatar.value) return;
top = Math.min(top, node.offsetTop); top = Math.min(top, node.offsetTop);
bottom = Math.max(bottom, node.offsetTop + node.offsetHeight); bottom = Math.max(bottom, node.offsetTop + node.offsetHeight);
@ -2956,13 +2958,43 @@ onBeforeUnmount(() => {
</script> </script>
<style scoped> <style scoped>
.floating-project-status { .composer-avatar {
position: absolute; position: absolute;
left: 5%; left: 0;
right: auto;
bottom: calc(100% + 6px); bottom: calc(100% + 6px);
z-index: auto; z-index: auto;
width: 90%; display: flex;
max-width: 90%; align-items: flex-end;
justify-content: flex-start;
width: 45px;
height: 64px;
pointer-events: auto;
color: var(--claude-text);
}
.floating-status-row {
position: absolute;
left: 49px;
right: 49px;
bottom: calc(100% + 6px);
z-index: auto;
height: 64px;
display: flex;
align-items: flex-end;
justify-content: center;
pointer-events: none;
}
.floating-project-status {
position: relative;
left: auto;
right: auto;
bottom: auto;
flex: 1 1 auto;
width: 100%;
min-width: 0;
max-width: 100%;
height: 34px; height: 34px;
display: flex; display: flex;
align-items: center; align-items: center;
@ -2976,22 +3008,10 @@ onBeforeUnmount(() => {
pointer-events: auto; pointer-events: auto;
} }
.composer-avatar {
position: absolute;
left: 0;
bottom: calc(100% + 6px);
z-index: auto;
display: flex;
align-items: center;
justify-content: flex-start;
height: 40px;
pointer-events: auto;
color: var(--claude-text);
}
.composer-avatar .status-avatar { .composer-avatar .status-avatar {
display: block; display: block;
flex-shrink: 0; flex-shrink: 0;
margin-bottom: -5px;
} }
.composer-avatar__text { .composer-avatar__text {
@ -2999,20 +3019,26 @@ onBeforeUnmount(() => {
white-space: nowrap; white-space: nowrap;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
line-height: 16px;
color: var(--claude-text-secondary); color: var(--claude-text-secondary);
background: var(--chat-surface-color);
padding: 2px 8px;
border-radius: 9999px;
pointer-events: none; pointer-events: none;
z-index: 1; z-index: 1;
} }
.composer-avatar__text--right { .composer-avatar__text--right {
left: calc(100% + 8px); left: calc(100% + 4px);
top: 50%; right: auto;
transform: translateY(-50%); top: auto;
bottom: 0;
transform: none;
} }
.composer-avatar__text--top { .composer-avatar__text--top {
left: 0; left: -8px;
bottom: calc(100% + 4px); bottom: 40px;
transform: none; transform: none;
} }