From ddf962702d1cfa5b4e599bcb99fa7123292abaea Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Sat, 1 Nov 2025 16:43:36 +0800 Subject: [PATCH] feat(stage-web): voice & microphone for mobile web --- .../components/Layouts/InteractiveArea.vue | 23 ++++- .../Layouts/MobileInteractiveArea.vue | 15 +++ .../components/Widgets/IndicatorMicVolume.vue | 78 +++++++++++++++ apps/stage-web/src/pages/index.vue | 98 ++++++++++++++++++- cspell.config.yaml | 2 + 5 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 apps/stage-web/src/components/Widgets/IndicatorMicVolume.vue diff --git a/apps/stage-web/src/components/Layouts/InteractiveArea.vue b/apps/stage-web/src/components/Layouts/InteractiveArea.vue index 5631af69d..e02e62fe3 100644 --- a/apps/stage-web/src/components/Layouts/InteractiveArea.vue +++ b/apps/stage-web/src/components/Layouts/InteractiveArea.vue @@ -4,6 +4,7 @@ import type { ChatProvider } from '@xsai-ext/shared-providers' import WhisperWorker from '@proj-airi/stage-ui/libs/workers/worker?worker&url' import { toWAVBase64 } from '@proj-airi/audio' +import { HearingConfigDialog } from '@proj-airi/stage-ui/components' import { useMicVAD, useWhisper } from '@proj-airi/stage-ui/composables' import { useAudioContext } from '@proj-airi/stage-ui/stores/audio' import { useChatStore } from '@proj-airi/stage-ui/stores/chat' @@ -17,10 +18,11 @@ import { onMounted, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import ChatHistory from '../Widgets/ChatHistory.vue' +import IndicatorMicVolume from '../Widgets/IndicatorMicVolume.vue' const messageInput = ref('') const listening = ref(false) -const showMicrophoneSelect = ref(false) +const hearingDialogOpen = ref(false) const isComposing = ref(false) const providersStore = useProvidersStore() @@ -116,7 +118,7 @@ watch(enabled, async (value) => { } }) -watch(showMicrophoneSelect, async (value) => { +watch(hearingDialogOpen, async (value) => { if (value) { await askPermission() } @@ -164,6 +166,23 @@ onAfterMessageComposed(async () => { @compositionstart="isComposing = true" @compositionend="isComposing = false" /> + + + + diff --git a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue b/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue index 9ef7c6a1c..4e00009e8 100644 --- a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue +++ b/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue @@ -1,6 +1,7 @@ + + + diff --git a/apps/stage-web/src/pages/index.vue b/apps/stage-web/src/pages/index.vue index 01e7aae47..a337b5879 100644 --- a/apps/stage-web/src/pages/index.vue +++ b/apps/stage-web/src/pages/index.vue @@ -1,9 +1,20 @@