ux: 录音改为点击开始/点击结束

- 移除长按交互 (touchstart/touchend/mousedown/mouseup)
- 改为单击 toggle: 点击🎤开始录音, 再点击结束录音
- 按钮默认只显示🎤, 录音中显示🔴+秒数
- 下方提示改为'点击结束'
- 录音开始时清空 inputText
- 移除 suppressAutoSend 标志 (点击结束都是有意操作)
This commit is contained in:
yuzhiran
2026-07-05 19:41:21 +08:00
parent db1b3baa60
commit 50bb3c45ed
+14 -19
View File
@@ -61,14 +61,14 @@
<view class="input-bar" v-if="!isComplete"> <view class="input-bar" v-if="!isComplete">
<view class="mic-wrap"> <view class="mic-wrap">
<view class="mic-btn" :class="{ recording: isRecording }" @touchstart="startRecord" @touchend="stopRecord" @touchcancel="stopRecord" @mousedown="startRecord" @mouseup="stopRecord" @mouseleave="stopRecord"> <view class="mic-btn" :class="{ recording: isRecording }" @click="toggleRecord">
<text class="mic-icon">{{ isRecording ? '🔴' : '🎤' }}</text> <text class="mic-icon">{{ isRecording ? '🔴' : '🎤' }}</text>
<text class="mic-label">{{ isRecording ? recordingDuration + 's' : '按住' }}</text> <text class="mic-label" v-if="isRecording">{{ recordingDuration }}s</text>
</view> </view>
<text class="mic-hint" v-if="isRecording">松开结束</text> <text class="mic-hint" v-if="isRecording">点击结束</text>
</view> </view>
<view class="input-box"> <view class="input-box">
<textarea class="input-area" v-model="inputText" placeholder="按住🎤说话或输入回答..." :auto-height="true" :maxlength="2000" :disabled="aiLoading || isRecording" @confirm="sendAnswer" /> <textarea class="input-area" v-model="inputText" placeholder="点击🎤开始录音或输入回答..." :auto-height="true" :maxlength="2000" :disabled="aiLoading || isRecording" @confirm="sendAnswer" />
</view> </view>
<view class="send-btn" :class="{ disabled: !inputText.trim() || isRecording || aiLoading }" @click="sendAnswer"> <view class="send-btn" :class="{ disabled: !inputText.trim() || isRecording || aiLoading }" @click="sendAnswer">
<text class="send-icon"></text> <text class="send-icon"></text>
@@ -158,7 +158,7 @@ const isRecording = ref(false)
const recordingDuration = ref(0) const recordingDuration = ref(0)
let manager = null let manager = null
let recordTimer = null let recordTimer = null
let suppressAutoSend = false
function initRecorder() { function initRecorder() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
@@ -169,6 +169,7 @@ function initRecorder() {
manager.onStart = () => { manager.onStart = () => {
console.log('[WechatSI] start') console.log('[WechatSI] start')
isRecording.value = true isRecording.value = true
inputText.value = ''
recordingDuration.value = 0 recordingDuration.value = 0
recordTimer = setInterval(() => { recordingDuration.value++ }, 1000) recordTimer = setInterval(() => { recordingDuration.value++ }, 1000)
} }
@@ -179,7 +180,6 @@ function initRecorder() {
isRecording.value = false isRecording.value = false
recordingDuration.value = 0 recordingDuration.value = 0
if (recordTimer) { clearInterval(recordTimer); recordTimer = null } if (recordTimer) { clearInterval(recordTimer); recordTimer = null }
if (suppressAutoSend) { suppressAutoSend = false; return }
const text = res?.result?.trim() const text = res?.result?.trim()
if (text && text.length >= 2) { if (text && text.length >= 2) {
inputText.value = text inputText.value = text
@@ -413,10 +413,10 @@ const confirmExit = () => {
}) })
} }
function startRecord() { function toggleRecord() {
if (aiLoading.value || isComplete.value) return if (aiLoading.value || isComplete.value) return
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
if (isRecording.value) return if (!isRecording.value) {
if (!manager) initRecorder() if (!manager) initRecorder()
if (!manager) { if (!manager) {
uni.showToast({ title: '语音功能初始化失败', icon: 'none' }) uni.showToast({ title: '语音功能初始化失败', icon: 'none' })
@@ -424,22 +424,17 @@ function startRecord() {
} }
manager.start({ lang: 'zh_CN', duration: 60000 }) manager.start({ lang: 'zh_CN', duration: 60000 })
uni.vibrateShort({ type: 'medium' }) uni.vibrateShort({ type: 'medium' })
return
}
if (!manager) { isRecording.value = false; return }
if (recordTimer) { clearInterval(recordTimer); recordTimer = null }
recordingDuration.value = 0
manager.stop()
// #endif // #endif
// #ifndef MP-WEIXIN // #ifndef MP-WEIXIN
uni.showToast({ title: '语音输入仅支持小程序', icon: 'none' }) uni.showToast({ title: '语音输入仅支持小程序', icon: 'none' })
// #endif // #endif
} }
function stopRecord() {
if (!isRecording.value) return
if (!manager) { isRecording.value = false; return }
if (recordingDuration.value < 1) {
suppressAutoSend = true
if (recordTimer) { clearInterval(recordTimer); recordTimer = null }
recordingDuration.value = 0
}
manager.stop()
}
</script> </script>
<style scoped> <style scoped>