fix(stage): cover manual TTS stop across layouts

Add the stop-speaking control to the mobile shared input layout and the Electron Tamagotchi chat input so Web/shared, mobile, and Electron all expose the same manual TTS interruption path.

Signed-off-by: RainbowBird <git@luoling.moe>

Commit-Message-Assisted-by: Codex
This commit is contained in:
RainbowBird
2026-06-06 00:53:34 +08:00
parent 7549d4e9fb
commit bc9baa4e3e
2 changed files with 35 additions and 0 deletions
@@ -3,6 +3,7 @@ import type { ChatToolCallRendererRegistry } from '@proj-airi/stage-ui/component
import type { ChatHistoryItem } from '@proj-airi/stage-ui/types/chat'
import { errorMessageFrom } from '@moeru/std'
import { useStopSpeakingButton } from '@proj-airi/stage-layouts/composables/useStopSpeakingButton'
import { ChatHistory, JournalPreviewModal } from '@proj-airi/stage-ui/components'
import { useBackgroundStore } from '@proj-airi/stage-ui/stores/background'
import { useChatOrchestratorStore } from '@proj-airi/stage-ui/stores/chat'
@@ -56,6 +57,7 @@ const sendModeLabels = computed<Record<SendMode, string>>(() => ({
'ctrl-enter': t('stage.send-mode.ctrl-enter'),
'double-enter': t('stage.send-mode.double-enter'),
}))
const { showStopSpeakingButton, stopSpeakingFromChat } = useStopSpeakingButton()
const latestImageEntries = computed(() => {
if (!activeCardId.value)
@@ -322,6 +324,24 @@ async function handleRetryMessage(index: number) {
</DropdownMenuPortal>
</DropdownMenuRoot>
<button
v-if="showStopSpeakingButton"
data-testid="stop-speaking-button"
:class="[
'max-h-[10lh] min-h-[1lh]',
]"
bg="neutral-100 dark:neutral-800"
text="lg neutral-500 dark:neutral-400"
hover:text="primary-500 dark:primary-400"
flex items-center justify-center rounded-md p-2 outline-none
transition-colors transition-transform active:scale-95
title="Stop speaking"
aria-label="Stop speaking"
@click="stopSpeakingFromChat"
>
<div class="i-solar:stop-circle-bold-duotone" />
</button>
<button
:class="[
'max-h-[10lh] min-h-[1lh]',