feat: 优化语音输入时的样式和输入框
This commit is contained in:
@@ -21,18 +21,20 @@
|
||||
|
||||
<!-- 正常状态:显示输入框 -->
|
||||
<div class="input-wrapper">
|
||||
<input
|
||||
<textarea
|
||||
id="textarea"
|
||||
v-show="!isRecording"
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
rows="1"
|
||||
placeholder="Ask anything about your desired outfit"
|
||||
class="text-input"
|
||||
@keyup.enter="handleSend"
|
||||
/>
|
||||
@keydown="handleKeyDown"
|
||||
@input="handleInput"
|
||||
ref="textareaRef"
|
||||
></textarea>
|
||||
<div v-show="isRecording" class="recording-wrapper">
|
||||
<!-- <div class="recording-animation"> -->
|
||||
<AudioVisualizer />
|
||||
<AudioVisualizer ref="audioVisualizerRef" />
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,13 +53,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onUnmounted } from 'vue'
|
||||
import { ref, onUnmounted, nextTick } from 'vue'
|
||||
import AudioVisualizer from './AudioVisualizer.vue'
|
||||
import { showToast } from 'vant'
|
||||
|
||||
const emit = defineEmits(['send-message'])
|
||||
|
||||
const inputValue = ref<string>('')
|
||||
const isRecording = ref<boolean>(false)
|
||||
const audioVisualizerRef = ref<InstanceType<typeof AudioVisualizer> | null>(null)
|
||||
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
||||
const shortcutList: string[] = [
|
||||
'Suggest shoe styles',
|
||||
'Recommend evening bags',
|
||||
@@ -72,6 +77,34 @@ const handleSend = (): void => {
|
||||
console.log('input发送消息:', inputValue.value)
|
||||
emit('send-message', inputValue.value)
|
||||
inputValue.value = ''
|
||||
// 重置textarea高度
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.style.height = 'auto'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理键盘事件
|
||||
const handleKeyDown = (event: KeyboardEvent): void => {
|
||||
if (event.key === 'Enter' && !event.shiftKey) {
|
||||
event.preventDefault()
|
||||
handleSend()
|
||||
}
|
||||
}
|
||||
|
||||
// 处理输入事件,自动调整高度
|
||||
const handleInput = (): void => {
|
||||
if (textareaRef.value) {
|
||||
textareaRef.value.style.height = 'auto'
|
||||
|
||||
// const lineHeight = 4.8
|
||||
// const maxLines = 3
|
||||
// const maxHeight = lineHeight * maxLines
|
||||
|
||||
const scrollHeight = textareaRef.value.scrollHeight
|
||||
// const newHeight = Math.min(scrollHeight, maxHeight * 10)
|
||||
|
||||
textareaRef.value.style.height = `${scrollHeight}px`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +122,24 @@ onUnmounted(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const handleClickAudio = (): void => {
|
||||
const handleClickAudio = async (): Promise<void> => {
|
||||
isRecording.value = !isRecording.value
|
||||
|
||||
// 当开始录音时,等待DOM更新后触发AudioVisualizer重新计算
|
||||
if (isRecording.value) {
|
||||
await nextTick()
|
||||
// 立即尝试更新
|
||||
if (audioVisualizerRef.value) {
|
||||
audioVisualizerRef.value.updateLines?.()
|
||||
}
|
||||
// 快速重试
|
||||
setTimeout(() => {
|
||||
if (audioVisualizerRef.value) {
|
||||
audioVisualizerRef.value.updateLines?.()
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
|
||||
if (isRecording.value) {
|
||||
startRecording()
|
||||
} else {
|
||||
@@ -168,7 +216,8 @@ const startRecording = () => {
|
||||
speechRecognition.onerror = (event) => {
|
||||
console.error('语音识别错误:', event.error)
|
||||
isRecording.value = false
|
||||
alert('语音识别失败,请重试')
|
||||
// alert('语音识别失败,请重试')
|
||||
showToast(event.error)
|
||||
}
|
||||
|
||||
// 开始识别
|
||||
@@ -215,8 +264,8 @@ const stopRecording = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #efefef;
|
||||
padding: 0 4.85rem 0 5.2rem;
|
||||
height: 19.3rem;
|
||||
padding: 1.5rem 4.85rem 1.5rem 5.2rem;
|
||||
min-height: 19.3rem;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
@@ -236,6 +285,7 @@ const stopRecording = () => {
|
||||
margin-left: 5.59rem;
|
||||
margin-right: 3.5rem;
|
||||
background-color: #888;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
@@ -243,26 +293,22 @@ const stopRecording = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
// height: 100%;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
width: 100%;
|
||||
// height: 100%;
|
||||
height: auto;
|
||||
// min-height: 4.8rem;
|
||||
// max-height: 100%;
|
||||
max-height: 14.4rem;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
font-size: 4rem;
|
||||
font-family: 'robotoBold';
|
||||
font-weight: 400;
|
||||
line-height: 121%;
|
||||
// padding-right: 2rem;
|
||||
margin-right: 4.21rem;
|
||||
line-height: 4.8rem; /* 设置行高等于实际渲染高度,实现垂直居中 */
|
||||
padding: 0;
|
||||
color: #000;
|
||||
// resize: none;
|
||||
word-break: break-all;
|
||||
|
||||
&::placeholder {
|
||||
color: #888;
|
||||
@@ -288,6 +334,7 @@ const stopRecording = () => {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 4.8rem;
|
||||
}
|
||||
|
||||
.recording-animation {
|
||||
|
||||
Reference in New Issue
Block a user