mall_client/zyhs3_uniapp/pages/im/components/tui-chat/message-input/index.vue

529 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<view class="TUI-message-input-container">
<!-- 快捷菜单栏 -->
<!-- <view class="TUI-commom-function">
<view v-for="(item, index) in commonFunction" :key="index" class="TUI-commom-function-item" :data-function="item" @tap="handleCommonFunctions">{{ item.name }}</view>
</view> -->
<view class="TUI-message-input">
<!-- #ifndef H5 -->
<image class="TUI-icon" @tap="switchAudio" :src="isAudio ? 'https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/keyboard.svg' : 'https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/audio.svg'"></image>
<!-- #endif -->
<view v-if="!isAudio" class="TUI-message-input-main">
<input class="TUI-message-input-area" :adjust-position="true" cursor-spacing="20" v-model="inputText" @input="onInputValueChange" maxlength="140" type="text" placeholder-class="input-placeholder" placeholder="向Ta问候下吧~" @focus="inputBindFocus" @blur="inputBindBlur" />
</view>
<view v-else class="TUI-message-input-main" @longpress="handleLongPress" @touchmove="handleTouchMove" @touchend="handleTouchEnd" style="display: flex; justify-content: center; font-size: 32rpx; font-family: PingFangSC-Regular">
<text>{{ text }}</text>
</view>
<view class="TUI-message-input-functions" hover-class="none">
<image class="TUI-icon" @tap="handleEmoji" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/face-emoji.svg"></image>
<view v-if="!sendMessageBtn" @tap="handleExtensions">
<image class="TUI-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/more.svg"></image>
</view>
<view v-else class="TUI-sendMessage-btn" @tap="sendTextMessage">发送</view>
</view>
</view>
<view v-if="displayFlag === 'emoji'" class="TUI-Emoji-area">
<TUI-Emoji @enterEmoji="appendMessage"></TUI-Emoji>
</view>
<view v-if="displayFlag === 'extension'" class="TUI-Extensions">
<view class="TUI-Extension-slot" @tap="handleSendPicture">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/take-photo.svg"></image>
<view class="TUI-Extension-slot-name">拍摄照片</view>
</view>
<view class="TUI-Extension-slot" @tap="handleSendImage">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/send-img.svg"></image>
<view class="TUI-Extension-slot-name">发送图片</view>
</view>
<view class="TUI-Extension-slot" @tap="handleShootVideo">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/take-video.svg"></image>
<view class="TUI-Extension-slot-name">拍摄视频</view>
</view>
<view class="TUI-Extension-slot" @tap="handleSendVideo">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/send-video.svg"></image>
<view class="TUI-Extension-slot-name">发送视频</view>
</view>
<view class="TUI-Extension-slot" :data-value="1" @tap="handleCalling" v-if="conversation.type=='C2C'">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/audio-calling.svg"></image>
<view class="TUI-Extension-slot-name">语音通话</view>
</view>
<view class="TUI-Extension-slot" :data-value="2" @tap="handleCalling" v-if="conversation.type=='C2C'">
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/video-calling.svg"></image>
<view class="TUI-Extension-slot-name">视频通话</view>
</view>
<view class="TUI-Extension-slot" @tap="handleServiceEvaluation" v-if='false'>
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/service-assess.svg"></image>
<view class="TUI-Extension-slot-name">服务评价</view>
</view>
<view class="TUI-Extension-slot" @tap="handleSendOrder" v-if='false'>
<image class="TUI-Extension-icon" src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/assets/send-order.svg"></image>
<view class="TUI-Extension-slot-name">发送订单</view>
</view>
</view>
<TUI-Common-Words class="tui-cards" :display="displayCommonWords" @sendMessage="$handleSendTextMessage" @close="$handleCloseCards"></TUI-Common-Words>
<TUI-Order-List class="tui-cards" :display="displayOrderList" @sendCustomMessage="$handleSendCustomMessage" @close="$handleCloseCards"></TUI-Order-List>
<TUI-Service-Evaluation class="tui-cards" :display="displayServiceEvaluation" @sendCustomMessage="$handleSendCustomMessage" @close="$handleCloseCards"></TUI-Service-Evaluation>
</view>
<view class="record-modal" v-if="popupToggle" @longpress="handleLongPress" @touchmove="handleTouchMove" @touchend="handleTouchEnd">
<view class="wrapper">
<view class="modal-loading"></view>
</view>
<view class="modal-title">
{{ title }}
</view>
</view>
</view>
</template>
<script>
import TUIEmoji from '../message-elements/emoji/index';
import TUICommonWords from '../message-private/common-words/index';
import TUIOrderList from '../message-private/order-list/index';
import TUIServiceEvaluation from '../message-private/service-evaluation/index';
export default {
data() {
return {
inputText: '',
extensionArea: false,
sendMessageBtn: false,
displayFlag: '',
isAudio: false,
bottomVal: 0,
startPoint: 0,
popupToggle: false,
isRecording: false,
canSend: true,
text: '按住说话',
title: ' ',
notShow: false,
isShow: true,
recordTime: 0,
recordTimer: null,
commonFunction: [
{
name: '常用语',
key: '0'
},
{
name: '发送订单',
key: '1'
},
{
name: '服务评价',
key: '2'
}
],
displayServiceEvaluation: false,
displayCommonWords: false,
displayOrderList: false
};
},
components: {
TUIEmoji,
TUICommonWords,
TUIOrderList,
TUIServiceEvaluation
},
props: {
conversation: {
type: Object,
default: () => {}
}
},
beforeMount() {
// 加载声音录制管理器
this.recorderManager = uni.getRecorderManager();
this.recorderManager.onStop(res => {
clearInterval(this.recordTimer);
// 兼容 uniapp 打包appduration 和 fileSize 需要用户自己补充
// 文件大小 (音频码率) x 时间长度(单位:秒) / 8
let msg = {
duration: res.duration ? res.duration : this.recordTime * 1000,
tempFilePath: res.tempFilePath,
fileSize: res.fileSize ? res.fileSize : ((48 * this.recordTime) / 8) * 1024
};
uni.hideLoading();
// 兼容 uniapp 语音消息没有duration
if (this.canSend) {
if (msg.duration < 1000) {
uni.showToast({
title: '录音时间太短',
icon: 'none'
});
} else {
// res.tempFilePath 存储录音文件的临时路径
const message = uni.$TUIKit.createAudioMessage({
to: this.getToAccount(),
conversationType: this.conversation.type,
payload: {
file: msg
}
});
this.$sendTIMMessage(message);
}
}
this.setData({
startPoint: 0,
popupToggle: false,
isRecording: false,
canSend: true,
title: ' ',
text: '按住说话'
});
});
},
methods: {
switchAudio() {
this.setData({
isAudio: !this.isAudio,
text: '按住说话'
});
},
handleLongPress(e) {
this.recorderManager.start({
duration: 60000,
// 录音的时长,单位 ms最大值 60000010 分钟)
sampleRate: 44100,
// 采样率
numberOfChannels: 1,
// 录音通道数
encodeBitRate: 192000,
// 编码码率
format: 'aac' // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台Android、iOS、微信小程序和Web互通
});
this.setData({
startPoint: e.touches[0],
title: '正在录音',
// isRecording : true,
// canSend: true,
notShow: true,
isShow: false,
isRecording: true,
popupToggle: true,
recordTime: 0
});
this.recordTimer = setInterval(() => {
this.recordTime++;
}, 1000);
},
// 录音时的手势上划移动距离对应文案变化
handleTouchMove(e) {
if (this.isRecording) {
if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) {
this.setData({
text: '抬起停止',
title: '松开手指,取消发送',
canSend: false
});
} else if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) {
this.setData({
text: '抬起停止',
title: '上划可取消',
canSend: true
});
} else {
this.setData({
text: '抬起停止',
title: '正在录音',
canSend: true
});
}
}
},
// 手指离开页面滑动
handleTouchEnd() {
this.setData({
isRecording: false,
popupToggle: false
});
uni.hideLoading();
this.recorderManager.stop();
},
handleEmoji() {
let targetFlag = 'emoji';
if (this.displayFlag === 'emoji') {
targetFlag = '';
}
this.setData({
displayFlag: targetFlag
});
},
handleExtensions() {
let targetFlag = 'extension';
if (this.displayFlag === 'extension') {
targetFlag = '';
}
this.setData({
displayFlag: targetFlag
});
},
error(e) {
console.log(e.detail);
},
handleSendPicture() {
this.sendImageMessage('camera');
},
handleSendImage() {
this.sendImageMessage('album');
},
sendImageMessage(type) {
uni.chooseImage({
sourceType: [type],
count: 1,
success: res => {
if (res) {
const message = uni.$TUIKit.createImageMessage({
to: this.getToAccount(),
conversationType: this.conversation.type,
payload: {
file: res
},
onProgress: percent => {
message.percent = percent;
}
});
this.$sendTIMMessage(message);
}
}
});
},
handleShootVideo() {
this.sendVideoMessage('camera');
},
handleSendVideo() {
this.sendVideoMessage('album');
},
sendVideoMessage(type) {
uni.chooseVideo({
sourceType: [type],
// 来源相册或者拍摄
maxDuration: 60,
// 设置最长时间60s
camera: 'back',
// 后置摄像头
success: res => {
if (res) {
const message = uni.$TUIKit.createVideoMessage({
to: this.getToAccount(),
conversationType: this.conversation.type,
payload: {
file: res
},
onProgress: percent => {
message.percent = percent;
}
});
console.log(res);
this.$sendTIMMessage(message);
}
}
});
},
handleCommonFunctions(e) {
switch (e.target.dataset.function.key) {
case '0':
this.setData({
displayCommonWords: true
});
break;
case '1':
this.setData({
displayOrderList: true
});
break;
case '2':
this.setData({
displayServiceEvaluation: true
});
break;
default:
break;
}
},
handleSendOrder() {
this.setData({
displayOrderList: true
});
},
appendMessage(e) {
this.setData({
inputText: this.inputText + e.detail.message,
sendMessageBtn: true
});
},
getToAccount() {
if (!this.conversation || !this.conversation.conversationID) {
return '';
}
switch (this.conversation.type) {
case 'C2C':
return this.conversation.conversationID.replace('C2C', '');
case 'GROUP':
return this.conversation.conversationID.replace('GROUP', '');
default:
return this.conversation.conversationID;
}
},
handleCalling(e) {
if (this.conversation.type === 'GROUP') {
uni.navigateTo({
url: '/pages/im/group/invitation-friends/conversation?groupID=' + this.conversation.conversationID + '&callMediaType=' + e.currentTarget.dataset.value
});
return;
}
const type = e.currentTarget.dataset.value;
const { userID } = this.conversation.userProfile;
this.$emit('handleCall', {
detail: {
type,
userID
}
});
this.displayFlag = '';
},
sendTextMessage(msg, flag) {
const to = this.getToAccount();
const text = flag ? msg : this.inputText;
const message = uni.$TUIKit.createTextMessage({
to,
conversationType: this.conversation.type,
payload: {
text
}
});
this.setData({
inputText: '',
sendMessageBtn: false
});
this.$sendTIMMessage(message);
},
onInputValueChange(event) {
if (event.detail.value) {
this.setData({
sendMessageBtn: true
});
} else {
this.setData({
sendMessageBtn: false
});
}
},
$handleSendTextMessage(event) {
this.sendTextMessage(event.detail.message, true);
this.setData({
displayCommonWords: false
});
},
$handleSendCustomMessage(e) {
const message = uni.$TUIKit.createCustomMessage({
to: this.getToAccount(),
conversationType: this.conversation.type,
payload: e.detail.payload
});
this.$sendTIMMessage(message);
this.setData({
displayOrderList: false
});
},
$handleCloseCards(e) {
switch (e.detail.key) {
case '0':
this.setData({
displayCommonWords: false
});
break;
case '1':
this.setData({
displayOrderList: false
});
break;
case '2':
this.setData({
displayServiceEvaluation: false
});
break;
default:
break;
}
},
$sendTIMMessage(message) {
this.$emit('sendMessage', {
detail: {
message
}
});
uni.$TUIKit.sendMessage(message)
this.setData({
displayFlag: ''
});
},
handleClose() {
this.setData({
displayFlag: ''
});
},
handleServiceEvaluation() {
this.setData({
displayServiceEvaluation: true
});
},
inputBindFocus() {
console.log('占位:函数 inputBindFocus 未声明');
},
inputBindBlur() {
console.log('占位:函数 inputBindBlur 未声明');
}
}
};
</script>
<style>
@import './index.css';
</style>