@flexem/chat-box 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/miniprogram_dist/components/input-bar/index.js +3 -0
- package/miniprogram_dist/components/message/index.js +40 -5
- package/miniprogram_dist/components/message/index.wxml +7 -7
- package/miniprogram_dist/components/message/index.wxss +45 -14
- package/miniprogram_dist/index.js +110 -2
- package/miniprogram_dist/index.wxml +6 -1
- package/miniprogram_dist/index.wxss +1 -1
- package/miniprogram_dist/package.json +1 -1
- package/package.json +1 -1
|
@@ -637,7 +637,13 @@ Component({
|
|
|
637
637
|
const endPos = remaining.indexOf(marker, nearest.pos + 2);
|
|
638
638
|
if (endPos !== -1) {
|
|
639
639
|
const boldText = remaining.slice(nearest.pos + 2, endPos);
|
|
640
|
-
|
|
640
|
+
// 递归解析粗体内容,支持内部的链接等
|
|
641
|
+
const boldParts = this.processInlineElements(boldText);
|
|
642
|
+
// 给所有解析出的部分添加 bold 标记
|
|
643
|
+
boldParts.forEach(part => {
|
|
644
|
+
part.bold = true;
|
|
645
|
+
parts.push(part);
|
|
646
|
+
});
|
|
641
647
|
remaining = remaining.slice(endPos + 2);
|
|
642
648
|
} else {
|
|
643
649
|
// 没有闭合,当作普通文本
|
|
@@ -660,7 +666,13 @@ Component({
|
|
|
660
666
|
}
|
|
661
667
|
if (endPos !== -1) {
|
|
662
668
|
const italicText = remaining.slice(nearest.pos + 1, endPos);
|
|
663
|
-
|
|
669
|
+
// 递归解析斜体内容,支持内部的链接等
|
|
670
|
+
const italicParts = this.processInlineElements(italicText);
|
|
671
|
+
// 给所有解析出的部分添加 italic 标记
|
|
672
|
+
italicParts.forEach(part => {
|
|
673
|
+
part.italic = true;
|
|
674
|
+
parts.push(part);
|
|
675
|
+
});
|
|
664
676
|
remaining = remaining.slice(endPos + 1);
|
|
665
677
|
} else {
|
|
666
678
|
// 没有闭合,当作普通文本
|
|
@@ -964,6 +976,13 @@ Component({
|
|
|
964
976
|
this.triggerEvent('playvoice', { id, content: message.content });
|
|
965
977
|
},
|
|
966
978
|
|
|
979
|
+
/**
|
|
980
|
+
* 停止语音播放
|
|
981
|
+
*/
|
|
982
|
+
onStopVoice() {
|
|
983
|
+
this.triggerEvent('stopvoice');
|
|
984
|
+
},
|
|
985
|
+
|
|
967
986
|
/**
|
|
968
987
|
* 重新生成
|
|
969
988
|
*/
|
|
@@ -1003,10 +1022,26 @@ Component({
|
|
|
1003
1022
|
const touch = e.touches[0] || e.changedTouches[0];
|
|
1004
1023
|
if (!touch) return;
|
|
1005
1024
|
|
|
1006
|
-
//
|
|
1007
|
-
const
|
|
1025
|
+
// 获取屏幕宽度
|
|
1026
|
+
const systemInfo = wx.getWindowInfo();
|
|
1027
|
+
const screenWidth = systemInfo.windowWidth;
|
|
1028
|
+
|
|
1029
|
+
// 气泡菜单实际宽度:3个按钮(min-width 120rpx + padding 48rpx) + 外层 padding 16rpx = 约 520rpx
|
|
1030
|
+
// rpx 转 px: px = rpx / 750 * screenWidth
|
|
1031
|
+
const menuWidth = 520 / 750 * screenWidth;
|
|
1032
|
+
const menuHeight = 120;
|
|
1033
|
+
|
|
1034
|
+
// 计算气泡菜单位置(在触摸点上方,水平居中但不超出屏幕)
|
|
1008
1035
|
const top = touch.clientY - menuHeight - 20;
|
|
1009
|
-
|
|
1036
|
+
let left = touch.clientX;
|
|
1037
|
+
|
|
1038
|
+
// 确保菜单不超出左右边界(菜单使用 translateX(-50%))
|
|
1039
|
+
const halfMenu = menuWidth / 2;
|
|
1040
|
+
const minLeft = halfMenu + 16;
|
|
1041
|
+
const maxLeft = screenWidth - halfMenu - 16;
|
|
1042
|
+
|
|
1043
|
+
// 限制 left 在有效范围内
|
|
1044
|
+
left = Math.max(minLeft, Math.min(maxLeft, left));
|
|
1010
1045
|
|
|
1011
1046
|
this.setData({
|
|
1012
1047
|
showBubbleMenu: true,
|
|
@@ -83,10 +83,10 @@
|
|
|
83
83
|
<text class="code-lang">{{item.lang || 'code'}}</text>
|
|
84
84
|
<text class="code-copy" bindtap="onCopyCode" data-code="{{item.text}}">复制</text>
|
|
85
85
|
</view>
|
|
86
|
-
<!-- 使用
|
|
87
|
-
<view class="code-content-wrapper">
|
|
86
|
+
<!-- 使用 scroll-view 实现横向滚动 -->
|
|
87
|
+
<scroll-view class="code-content-wrapper" scroll-x="true" enhanced="true" show-scrollbar="true">
|
|
88
88
|
<text class="code-text" user-select="{{true}}">{{item.text}}</text>
|
|
89
|
-
</view>
|
|
89
|
+
</scroll-view>
|
|
90
90
|
</view>
|
|
91
91
|
|
|
92
92
|
<!-- 行内代码 -->
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
<text class="bubble-menu-text">复制全文</text>
|
|
252
252
|
</view>
|
|
253
253
|
<view class="bubble-menu-item" bindtap="onSelectCopy">
|
|
254
|
-
<
|
|
254
|
+
<text class="bubble-menu-icon-text">[A]</text>
|
|
255
255
|
<text class="bubble-menu-text">节选复制</text>
|
|
256
256
|
</view>
|
|
257
257
|
<view class="bubble-menu-item" bindtap="onBubblePlayVoice">
|
|
@@ -265,12 +265,12 @@
|
|
|
265
265
|
|
|
266
266
|
<!-- 正在输入指示器 -->
|
|
267
267
|
<view wx:if="{{message.isStreaming}}" class="typing-indicator">
|
|
268
|
-
<!--
|
|
269
|
-
<
|
|
268
|
+
<!-- 语音播放中时显示播放动画,点击可停止 -->
|
|
269
|
+
<view wx:if="{{isPlaying}}" class="voice-playing-streaming" bindtap="onStopVoice">
|
|
270
270
|
<view class="voice-bar"></view>
|
|
271
271
|
<view class="voice-bar"></view>
|
|
272
272
|
<view class="voice-bar"></view>
|
|
273
|
-
</
|
|
273
|
+
</view>
|
|
274
274
|
<!-- 未播放时显示打字动画 -->
|
|
275
275
|
<block wx:else>
|
|
276
276
|
<view class="typing-dot"></view>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
.ai-message {
|
|
17
17
|
flex-direction: row;
|
|
18
|
+
overflow: visible;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/* 头像 */
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
flex: 1;
|
|
47
48
|
align-items: flex-start;
|
|
48
49
|
max-width: calc(100%);
|
|
50
|
+
overflow: visible;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/* 消息气泡 */
|
|
@@ -67,7 +69,6 @@
|
|
|
67
69
|
.ai-bubble {
|
|
68
70
|
background-color: #fff;
|
|
69
71
|
color: #333;
|
|
70
|
-
border-bottom-left-radius: 8rpx;
|
|
71
72
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -132,8 +133,12 @@
|
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
.thinking-icon {
|
|
135
|
-
width: 32rpx;
|
|
136
|
-
height: 32rpx;
|
|
136
|
+
width: 32rpx !important;
|
|
137
|
+
height: 32rpx !important;
|
|
138
|
+
min-width: 32rpx !important;
|
|
139
|
+
min-height: 32rpx !important;
|
|
140
|
+
max-width: 32rpx !important;
|
|
141
|
+
max-height: 32rpx !important;
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
.thinking-title {
|
|
@@ -267,12 +272,11 @@
|
|
|
267
272
|
overflow-x: auto;
|
|
268
273
|
}
|
|
269
274
|
|
|
270
|
-
/* 代码内容容器 -
|
|
275
|
+
/* 代码内容容器 - 使用 scroll-view 实现横向滚动 */
|
|
271
276
|
.code-content-wrapper {
|
|
272
277
|
padding: 20rpx;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
-webkit-overflow-scrolling: touch;
|
|
278
|
+
width: 100%;
|
|
279
|
+
box-sizing: border-box;
|
|
276
280
|
}
|
|
277
281
|
|
|
278
282
|
.code-text {
|
|
@@ -282,7 +286,6 @@
|
|
|
282
286
|
white-space: pre;
|
|
283
287
|
word-break: normal;
|
|
284
288
|
display: inline-block;
|
|
285
|
-
min-width: 100%;
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
/* 行内代码 */
|
|
@@ -429,7 +432,7 @@
|
|
|
429
432
|
}
|
|
430
433
|
|
|
431
434
|
.message-time {
|
|
432
|
-
font-size: 22rpx;
|
|
435
|
+
font-size: 22rpx !important;
|
|
433
436
|
color: #999;
|
|
434
437
|
}
|
|
435
438
|
|
|
@@ -461,9 +464,13 @@
|
|
|
461
464
|
}
|
|
462
465
|
|
|
463
466
|
.action-icon-img {
|
|
464
|
-
width: 40rpx;
|
|
465
|
-
height: 40rpx;
|
|
466
|
-
|
|
467
|
+
width: 40rpx !important;
|
|
468
|
+
height: 40rpx !important;
|
|
469
|
+
min-width: 40rpx !important;
|
|
470
|
+
min-height: 40rpx !important;
|
|
471
|
+
max-width: 40rpx !important;
|
|
472
|
+
max-height: 40rpx !important;
|
|
473
|
+
padding: 8rpx !important;
|
|
467
474
|
}
|
|
468
475
|
|
|
469
476
|
.user-bubble .action-icon-img {
|
|
@@ -482,6 +489,17 @@
|
|
|
482
489
|
padding: 8rpx;
|
|
483
490
|
}
|
|
484
491
|
|
|
492
|
+
/* 流式消息中的语音播放动画(可点击停止) */
|
|
493
|
+
.voice-playing-streaming {
|
|
494
|
+
display: flex;
|
|
495
|
+
align-items: center;
|
|
496
|
+
justify-content: center;
|
|
497
|
+
gap: 4rpx;
|
|
498
|
+
padding: 8rpx 16rpx;
|
|
499
|
+
background-color: rgba(0, 122, 255, 0.1);
|
|
500
|
+
border-radius: 20rpx;
|
|
501
|
+
}
|
|
502
|
+
|
|
485
503
|
.voice-bar {
|
|
486
504
|
width: 6rpx;
|
|
487
505
|
height: 20rpx;
|
|
@@ -610,12 +628,25 @@
|
|
|
610
628
|
}
|
|
611
629
|
|
|
612
630
|
.bubble-menu-icon {
|
|
613
|
-
width: 48rpx;
|
|
614
|
-
height: 48rpx;
|
|
631
|
+
width: 48rpx !important;
|
|
632
|
+
height: 48rpx !important;
|
|
633
|
+
min-width: 48rpx !important;
|
|
634
|
+
min-height: 48rpx !important;
|
|
635
|
+
max-width: 48rpx !important;
|
|
636
|
+
max-height: 48rpx !important;
|
|
615
637
|
margin-bottom: 8rpx;
|
|
616
638
|
filter: brightness(0) invert(1);
|
|
617
639
|
}
|
|
618
640
|
|
|
641
|
+
.bubble-menu-icon-text {
|
|
642
|
+
font-size: 36rpx;
|
|
643
|
+
font-weight: bold;
|
|
644
|
+
color: #fff;
|
|
645
|
+
margin-bottom: 8rpx;
|
|
646
|
+
height: 48rpx;
|
|
647
|
+
line-height: 48rpx;
|
|
648
|
+
}
|
|
649
|
+
|
|
619
650
|
.bubble-menu-text {
|
|
620
651
|
font-size: 24rpx;
|
|
621
652
|
color: #fff;
|
|
@@ -82,6 +82,7 @@ Component({
|
|
|
82
82
|
keyboardHeight: 0, // 键盘高度
|
|
83
83
|
attachmentHeight: 0, // 附件预览区域高度
|
|
84
84
|
inputBarHeight: 0, // 输入框高度增量(多行时相对于单行的额外高度,rpx转px)
|
|
85
|
+
safeAreaBottom: 0, // 底部安全区域高度
|
|
85
86
|
|
|
86
87
|
// 会话相关
|
|
87
88
|
currentSession: {}, // 当前会话
|
|
@@ -98,6 +99,7 @@ Component({
|
|
|
98
99
|
// 加载状态
|
|
99
100
|
isStreaming: false, // 是否正在流式输出
|
|
100
101
|
lastScrollTime: 0, // 上次滚动时间(用于节流)
|
|
102
|
+
userScrolledUp: false, // 用户是否手动向上滚动(流式输出时暂停自动滚动)
|
|
101
103
|
hasMoreHistory: false, // 是否有更多历史消息
|
|
102
104
|
isLoadingHistory: false, // 是否正在加载历史消息
|
|
103
105
|
historyPage: 1, // 历史消息页码
|
|
@@ -159,6 +161,20 @@ Component({
|
|
|
159
161
|
}
|
|
160
162
|
},
|
|
161
163
|
|
|
164
|
+
/**
|
|
165
|
+
* 页面生命周期(组件所在页面的生命周期)
|
|
166
|
+
*/
|
|
167
|
+
pageLifetimes: {
|
|
168
|
+
hide() {
|
|
169
|
+
// 页面隐藏时停止语音播放(如用户点击小程序关闭按钮)
|
|
170
|
+
audio.stop();
|
|
171
|
+
this.setData({
|
|
172
|
+
playingMessageId: null,
|
|
173
|
+
synthesizingMessageId: null
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
162
178
|
/**
|
|
163
179
|
* 组件的方法列表
|
|
164
180
|
*/
|
|
@@ -179,11 +195,15 @@ Component({
|
|
|
179
195
|
// 导航栏总高度 = 胶囊按钮底部 + 与顶部相同的边距
|
|
180
196
|
const navBarHeight = menuButton.bottom + (menuButton.top - statusBarHeight);
|
|
181
197
|
|
|
198
|
+
// 计算底部安全区域高度
|
|
199
|
+
const safeAreaBottom = systemInfo.screenHeight - systemInfo.safeArea.bottom;
|
|
200
|
+
|
|
182
201
|
this.setData({
|
|
183
202
|
statusBarHeight,
|
|
184
203
|
menuButtonTop,
|
|
185
204
|
menuButtonHeight,
|
|
186
|
-
navBarHeight
|
|
205
|
+
navBarHeight,
|
|
206
|
+
safeAreaBottom
|
|
187
207
|
});
|
|
188
208
|
},
|
|
189
209
|
|
|
@@ -340,6 +360,13 @@ Component({
|
|
|
340
360
|
* 返回上一页
|
|
341
361
|
*/
|
|
342
362
|
onBack() {
|
|
363
|
+
// 停止语音播放
|
|
364
|
+
audio.stop();
|
|
365
|
+
this.setData({
|
|
366
|
+
playingMessageId: null,
|
|
367
|
+
synthesizingMessageId: null
|
|
368
|
+
});
|
|
369
|
+
|
|
343
370
|
// 触发 back 事件,让外部处理返回逻辑
|
|
344
371
|
this.triggerEvent('back');
|
|
345
372
|
|
|
@@ -685,6 +712,12 @@ Component({
|
|
|
685
712
|
|
|
686
713
|
if (!content && (!attachments || attachments.length === 0)) return;
|
|
687
714
|
|
|
715
|
+
// 停止正在播放的语音
|
|
716
|
+
if (this.data.playingMessageId) {
|
|
717
|
+
audio.stop();
|
|
718
|
+
this.setData({ playingMessageId: null, synthesizingMessageId: null });
|
|
719
|
+
}
|
|
720
|
+
|
|
688
721
|
// 检查登录状态
|
|
689
722
|
if (!this.getAiChatUrl() || !this.data.userToken) {
|
|
690
723
|
this.triggerEvent('login');
|
|
@@ -764,6 +797,7 @@ Component({
|
|
|
764
797
|
|
|
765
798
|
this.setData({
|
|
766
799
|
isStreaming: true,
|
|
800
|
+
userScrolledUp: false, // 重置用户滚动状态
|
|
767
801
|
streamingMessage: {
|
|
768
802
|
id: aiMessageId, // 使用固定 ID,便于跟踪播放状态
|
|
769
803
|
role: 'assistant',
|
|
@@ -989,6 +1023,12 @@ Component({
|
|
|
989
1023
|
return;
|
|
990
1024
|
}
|
|
991
1025
|
|
|
1026
|
+
// 停止正在播放的语音
|
|
1027
|
+
if (this.data.playingMessageId) {
|
|
1028
|
+
audio.stop();
|
|
1029
|
+
this.setData({ playingMessageId: null, synthesizingMessageId: null });
|
|
1030
|
+
}
|
|
1031
|
+
|
|
992
1032
|
// 重新生成应该是针对用户消息的
|
|
993
1033
|
if (message.role !== 'user') {
|
|
994
1034
|
console.error('重新生成只能用于用户消息');
|
|
@@ -1056,6 +1096,12 @@ Component({
|
|
|
1056
1096
|
return;
|
|
1057
1097
|
}
|
|
1058
1098
|
|
|
1099
|
+
// 停止正在播放的语音
|
|
1100
|
+
if (this.data.playingMessageId) {
|
|
1101
|
+
audio.stop();
|
|
1102
|
+
this.setData({ playingMessageId: null, synthesizingMessageId: null });
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1059
1105
|
this.setData({
|
|
1060
1106
|
editingContent: message.content,
|
|
1061
1107
|
editingMessage: message
|
|
@@ -1176,6 +1222,30 @@ Component({
|
|
|
1176
1222
|
}
|
|
1177
1223
|
},
|
|
1178
1224
|
|
|
1225
|
+
/**
|
|
1226
|
+
* 停止语音播放
|
|
1227
|
+
*/
|
|
1228
|
+
onStopVoice() {
|
|
1229
|
+
audio.stop();
|
|
1230
|
+
this.setData({
|
|
1231
|
+
playingMessageId: null,
|
|
1232
|
+
synthesizingMessageId: null
|
|
1233
|
+
});
|
|
1234
|
+
},
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* 按住说话开始时停止语音播放
|
|
1238
|
+
*/
|
|
1239
|
+
onVoiceRecordStart() {
|
|
1240
|
+
if (this.data.playingMessageId) {
|
|
1241
|
+
audio.stop();
|
|
1242
|
+
this.setData({
|
|
1243
|
+
playingMessageId: null,
|
|
1244
|
+
synthesizingMessageId: null
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
|
|
1179
1249
|
/**
|
|
1180
1250
|
* 播放消息语音
|
|
1181
1251
|
*/
|
|
@@ -1312,12 +1382,17 @@ Component({
|
|
|
1312
1382
|
|
|
1313
1383
|
/**
|
|
1314
1384
|
* 滚动到底部(带节流,流式输出时减少滚动频率)
|
|
1315
|
-
* @param {boolean} force -
|
|
1385
|
+
* @param {boolean} force - 是否强制滚动(不受节流限制和用户滚动状态限制)
|
|
1316
1386
|
*/
|
|
1317
1387
|
scrollToBottom(force = false) {
|
|
1318
1388
|
const now = Date.now();
|
|
1319
1389
|
const throttleInterval = 200; // 200ms 节流
|
|
1320
1390
|
|
|
1391
|
+
// 流式输出时,如果用户手动向上滚动了,不自动滚动(除非强制)
|
|
1392
|
+
if (!force && this.data.isStreaming && this.data.userScrolledUp) {
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1321
1396
|
// 非强制模式下,流式输出时进行节流
|
|
1322
1397
|
if (!force && this.data.isStreaming) {
|
|
1323
1398
|
if (now - this.data.lastScrollTime < throttleInterval) {
|
|
@@ -1350,6 +1425,39 @@ Component({
|
|
|
1350
1425
|
}
|
|
1351
1426
|
},
|
|
1352
1427
|
|
|
1428
|
+
/**
|
|
1429
|
+
* 滚动事件处理
|
|
1430
|
+
* 检测用户是否手动向上滚动
|
|
1431
|
+
*/
|
|
1432
|
+
onScroll(e) {
|
|
1433
|
+
// 只在流式输出时检测
|
|
1434
|
+
if (!this.data.isStreaming) {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
const { deltaY } = e.detail;
|
|
1439
|
+
|
|
1440
|
+
// deltaY > 0 表示向上滚动(手指向下滑)
|
|
1441
|
+
// 如果用户向上滚动,标记为手动滚动
|
|
1442
|
+
if (deltaY > 0) {
|
|
1443
|
+
if (!this.data.userScrolledUp) {
|
|
1444
|
+
this.setData({ userScrolledUp: true });
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
},
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* 滚动到底部事件
|
|
1451
|
+
* 用户滚动到底部时,恢复自动滚动
|
|
1452
|
+
*/
|
|
1453
|
+
onScrollToLower() {
|
|
1454
|
+
if (this.data.isStreaming && this.data.userScrolledUp) {
|
|
1455
|
+
this.setData({ userScrolledUp: false });
|
|
1456
|
+
// 恢复后立即触发一次滚动,确保跟上最新数据
|
|
1457
|
+
this.scrollToBottom(true);
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
|
|
1353
1461
|
/**
|
|
1354
1462
|
* 格式化时间(完整格式:2025/09/18 17:41:22)
|
|
1355
1463
|
*/
|
|
@@ -87,12 +87,15 @@
|
|
|
87
87
|
<!-- 消息列表区域 -->
|
|
88
88
|
<scroll-view
|
|
89
89
|
class="message-list"
|
|
90
|
-
style="margin-top: {{navBarHeight}}px; padding-bottom: {{keyboardHeight > 0 ? (keyboardHeight + inputBarHeight + 40) : (
|
|
90
|
+
style="margin-top: {{navBarHeight}}px; padding-bottom: {{keyboardHeight > 0 ? (keyboardHeight + inputBarHeight + 40) : (50 + safeAreaBottom + attachmentHeight + inputBarHeight)}}px;"
|
|
91
91
|
scroll-y="true"
|
|
92
92
|
scroll-into-view="{{scrollToMessage}}"
|
|
93
93
|
enhanced="true"
|
|
94
94
|
show-scrollbar="false"
|
|
95
95
|
bindscrolltoupper="onScrollToUpper"
|
|
96
|
+
bindscroll="onScroll"
|
|
97
|
+
lower-threshold="50"
|
|
98
|
+
bindscrolltolower="onScrollToLower"
|
|
96
99
|
>
|
|
97
100
|
<!-- 加载更多 -->
|
|
98
101
|
<view wx:if="{{hasMoreHistory}}" class="load-more-history">
|
|
@@ -129,6 +132,7 @@
|
|
|
129
132
|
isPlaying="{{playingMessageId === streamingMessage.id}}"
|
|
130
133
|
isSynthesizing="{{synthesizingMessageId === streamingMessage.id}}"
|
|
131
134
|
isStreaming="{{true}}"
|
|
135
|
+
bind:stopvoice="onStopVoice"
|
|
132
136
|
/>
|
|
133
137
|
</view>
|
|
134
138
|
|
|
@@ -162,6 +166,7 @@
|
|
|
162
166
|
bind:keyboardheight="onKeyboardHeight"
|
|
163
167
|
bind:attachmentheight="onAttachmentHeight"
|
|
164
168
|
bind:inputheight="onInputHeight"
|
|
169
|
+
bind:voicerecordstart="onVoiceRecordStart"
|
|
165
170
|
/>
|
|
166
171
|
|
|
167
172
|
<!-- 免责声明(键盘弹出时隐藏) -->
|