|
@@ -1,26 +1,33 @@
|
|
<template>
|
|
<template>
|
|
<view class="container">
|
|
<view class="container">
|
|
- <view id="topnav" class="topnav flex-start" :style="{'height':`${topbarOffsetHeight-statusBarHeight}px`,'padding-top':`${statusBarHeight}px`}">
|
|
|
|
|
|
+ <view id="topnav" class="topnav flex-start"
|
|
|
|
+ :style="{ 'height': `${topbarOffsetHeight - statusBarHeight}px`, 'padding-top': `${statusBarHeight}px` }">
|
|
<view class="nav-item flex-center" @click="back">
|
|
<view class="nav-item flex-center" @click="back">
|
|
<image :src="`${assetsUrl}back.png`" mode="widthFix" class="nav-img"></image>
|
|
<image :src="`${assetsUrl}back.png`" mode="widthFix" class="nav-img"></image>
|
|
</view>
|
|
</view>
|
|
<view class="nav-center flex-center">
|
|
<view class="nav-center flex-center">
|
|
<view class="nav-text font32 fw600">
|
|
<view class="nav-text font32 fw600">
|
|
- {{userInfo.nick}}
|
|
|
|
|
|
+ {{ userInfo.nick }}
|
|
</view>
|
|
</view>
|
|
- <view class="nav-tip font20 fw400" >
|
|
|
|
- <text></text>{{onlineState}} · {{userInfo.distance}}
|
|
|
|
|
|
+ <view class="nav-tip font20 fw400">
|
|
|
|
+ <text></text>{{ onlineState }} · {{ userInfo.distance }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
-
|
|
|
|
|
|
+
|
|
<view class="nav-item"></view>
|
|
<view class="nav-item"></view>
|
|
</view>
|
|
</view>
|
|
- <view class="message-list" :style="{'height': `${scrollHeight}px`,'margin-top':`${topbarOffsetHeight}px`}">
|
|
|
|
- <TUI-message-list id="message-list" ref="messageList" :conversation="conversation" :scrollHeight="scrollHeight" :topbarOffsetHeight="topbarOffsetHeight" />
|
|
|
|
|
|
+ <view class="message-list" :style="[{ 'height': `${scrollHeight}px`, 'margin-top': `${topbarOffsetHeight}px` }]">
|
|
|
|
+ <!-- <view class="message-list" :style="[messageStyle]"> -->
|
|
|
|
+ <TUI-message-list id="message-list" ref="messageList" :conversation="conversation" :scrollHeight="scrollHeight"
|
|
|
|
+ :topbarOffsetHeight="topbarOffsetHeight" />
|
|
</view>
|
|
</view>
|
|
- <view class="talk-box" id="talk-box" @touchmove="prevent()">
|
|
|
|
|
|
+ <view class="talk-box" :style="[{ 'bottom': `${bottomVal}px` }]" id="talk-box" @touchmove="prevent()">
|
|
<view class="input-box flex-between">
|
|
<view class="input-box flex-between">
|
|
- <input type="text" class="input" confirm-type="send" placeholder="请输入消息…" :adjust-position="false" v-model="inputText" placeholder-style="color:#7D7DA4 ;font-size:24rpx" @confirm="sendTextMessage">
|
|
|
|
|
|
+ <!-- <van-field v-model="inputText" label="文本" placeholder="请输入消息…" /> -->
|
|
|
|
+ <!-- <input type="text" class="input" confirm-type="send" placeholder="请输入消息…" :adjust-position="true" v-model="inputText" placeholder-style="color:#7D7DA4 ;font-size:24rpx" @confirm="sendTextMessage"> -->
|
|
|
|
+ <input class="TUI-message-input-area" :adjust-position="false" cursor-spacing="20" v-model="inputText"
|
|
|
|
+ @confirm="sendTextMessage" maxlength="140" type="text" placeholder-class="input-placeholder" placeholder-style="color:#7D7DA4 ;font-size:24rpx"
|
|
|
|
+ placeholder="请输入消息…" @focus="inputBindFocus" @blur="inputBindBlur" />
|
|
<view class="input-btn font22 fw400" @click="sendTextMessage">
|
|
<view class="input-btn font22 fw400" @click="sendTextMessage">
|
|
发送
|
|
发送
|
|
</view>
|
|
</view>
|
|
@@ -31,388 +38,404 @@
|
|
<image :src="`${assetsUrl}talk-video.png`" mode="aspectFit" class="act-img" @click="showActionPanel(2)"></image>
|
|
<image :src="`${assetsUrl}talk-video.png`" mode="aspectFit" class="act-img" @click="showActionPanel(2)"></image>
|
|
<image :src="`${assetsUrl}talk-emo.png`" mode="aspectFit" class="act-img" @click="showActionPanel(3)"></image>
|
|
<image :src="`${assetsUrl}talk-emo.png`" mode="aspectFit" class="act-img" @click="showActionPanel(3)"></image>
|
|
</view>
|
|
</view>
|
|
- <view class="action-panel" :style="{'padding-bottom':`${showActionIndex===-1?'68rpx':'20rpx'}`}">
|
|
|
|
- <view class="voice-panel flex-center" v-if="showActionIndex===0">
|
|
|
|
|
|
+ <view class="action-panel" :style="{ 'padding-bottom': `${showActionIndex === -1 ? '68rpx' : '20rpx'}` }">
|
|
|
|
+ <view class="voice-panel flex-center" v-if="showActionIndex === 0">
|
|
<view class="voice-text font22 fw400">
|
|
<view class="voice-text font22 fw400">
|
|
- {{voiceText}}
|
|
|
|
|
|
+ {{ voiceText }}
|
|
</view>
|
|
</view>
|
|
- <image :src="`${assetsUrl}talk-voice-${isRecording?'delete':'open'}.png`" mode="aspectFill" class="voice-img" @longpress="handleLongPress" @touchmove="handleTouchMove" @touchend="handleTouchEnd"></image>
|
|
|
|
|
|
+ <image :src="`${assetsUrl}talk-voice-${isRecording ? 'delete' : 'open'}.png`" mode="aspectFill" class="voice-img"
|
|
|
|
+ @longpress="handleLongPress" @touchmove="handleTouchMove" @touchend="handleTouchEnd"></image>
|
|
</view>
|
|
</view>
|
|
- <view class="emoji-box" v-if="showActionIndex===3">
|
|
|
|
|
|
+ <view class="emoji-box" v-if="showActionIndex === 3">
|
|
<TUI-Emoji @enterEmoji="appendMessage"></TUI-Emoji>
|
|
<TUI-Emoji @enterEmoji="appendMessage"></TUI-Emoji>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="videoPlay" class="container-box" @tap.stop="stopVideoHander">
|
|
<view v-if="videoPlay" class="container-box" @tap.stop="stopVideoHander">
|
|
- <video
|
|
|
|
- v-if="videoPlay"
|
|
|
|
- class="video-message"
|
|
|
|
- :src="videoMessage.payload.videoUrl||videoMessage.videoUrl"
|
|
|
|
- :poster="videoMessage.payload.thumbUrl||videoMessage.videoCover"
|
|
|
|
- object-fit="cover"
|
|
|
|
- error="videoError"
|
|
|
|
- autoplay="true"
|
|
|
|
- direction="0"
|
|
|
|
- show-fullscreen-btn="false"
|
|
|
|
- :style="{'width':`${videoMessage.payload.thumbWidth||videoMessage.width}px`,'height':`${videoMessage.payload.thumbHeight||videoMessage.height}px`}"
|
|
|
|
- />
|
|
|
|
|
|
+ <video v-if="videoPlay" class="video-message" :src="videoMessage.payload.videoUrl || videoMessage.videoUrl"
|
|
|
|
+ :poster="videoMessage.payload.thumbUrl || videoMessage.videoCover" object-fit="cover" error="videoError"
|
|
|
|
+ autoplay="true" direction="0" show-fullscreen-btn="false"
|
|
|
|
+ :style="{ 'width': `${videoMessage.payload.thumbWidth || videoMessage.width}px`, 'height': `${videoMessage.payload.thumbHeight || videoMessage.height}px` }" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
- import TUIEmoji from '../../components/tui-chat/message-elements/emoji/index';
|
|
|
|
- import TUIMessageList from '../../components/tui-chat/message-list/index';
|
|
|
|
-
|
|
|
|
- export default {
|
|
|
|
- components: {
|
|
|
|
- TUIMessageList,
|
|
|
|
- TUIEmoji
|
|
|
|
|
|
+import TUIEmoji from '../../components/tui-chat/message-elements/emoji/index';
|
|
|
|
+import TUIMessageList from '../../components/tui-chat/message-list/index';
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ components: {
|
|
|
|
+ TUIMessageList,
|
|
|
|
+ TUIEmoji
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ assetsUrl: this.$util.assetsUrl,
|
|
|
|
+ scrollHeight: 0,
|
|
|
|
+ topNavHeight: 0,
|
|
|
|
+ userInfo: null,
|
|
|
|
+ messageList: [],
|
|
|
|
+ message: null,//消息实例
|
|
|
|
+ onlineState: '',
|
|
|
|
+ scrollRefreshing: false,
|
|
|
|
+ scrollTriggered: true,
|
|
|
|
+ conversation: '',
|
|
|
|
+ conversationID: '',
|
|
|
|
+ inputText: '',
|
|
|
|
+ showSendBtn: false,
|
|
|
|
+ showActionIndex: -1,
|
|
|
|
+ recorderManager: null,
|
|
|
|
+ voiceText: '按住说话,松手发送',
|
|
|
|
+ recordTimeTotal: 60,//最大长度,30秒
|
|
|
|
+ isRecording: false,
|
|
|
|
+ canSend: false,
|
|
|
|
+ startPoint: 0,
|
|
|
|
+ videoPlay: false,
|
|
|
|
+ videoMessage: {},
|
|
|
|
+ bottomVal: 0 // 底部bottom
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ statusBarHeight() {
|
|
|
|
+ return this.$store.state.statusBarHeight;
|
|
},
|
|
},
|
|
- data() {
|
|
|
|
- return {
|
|
|
|
- assetsUrl:this.$util.assetsUrl,
|
|
|
|
- scrollHeight:0,
|
|
|
|
- topNavHeight:0,
|
|
|
|
- userInfo:null,
|
|
|
|
- messageList:[],
|
|
|
|
- message:null,//消息实例
|
|
|
|
- onlineState:'',
|
|
|
|
- scrollRefreshing:false,
|
|
|
|
- scrollTriggered:true,
|
|
|
|
- conversation:'',
|
|
|
|
- conversationID: '',
|
|
|
|
- inputText:'',
|
|
|
|
- showSendBtn:false,
|
|
|
|
- showActionIndex:-1,
|
|
|
|
- recorderManager:null,
|
|
|
|
- voiceText:'按住说话,松手发送',
|
|
|
|
- recordTimeTotal:60,//最大长度,30秒
|
|
|
|
- isRecording:false,
|
|
|
|
- canSend:false,
|
|
|
|
- startPoint:0,
|
|
|
|
- videoPlay: false,
|
|
|
|
- videoMessage: {},
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ topbarOffsetHeight() {
|
|
|
|
+ return this.$store.state.topbarOffsetHeight;
|
|
},
|
|
},
|
|
- computed: {
|
|
|
|
- statusBarHeight() {
|
|
|
|
- return this.$store.state.statusBarHeight;
|
|
|
|
- },
|
|
|
|
- topbarOffsetHeight() {
|
|
|
|
- return this.$store.state.topbarOffsetHeight;
|
|
|
|
|
|
+ messageStyle() {
|
|
|
|
+ let obj = {
|
|
|
|
+ 'height': `${this.scrollHeight}px`,
|
|
|
|
+ 'margin-top': `${this.topbarOffsetHeight}px`
|
|
}
|
|
}
|
|
- },
|
|
|
|
- created() {
|
|
|
|
- uni.$on('videoPlayerHandler', value => {
|
|
|
|
- this.videoPlay = value.isPlay;
|
|
|
|
- this.videoMessage = value.message;
|
|
|
|
- });
|
|
|
|
- uni.authorize({
|
|
|
|
- scope:'scope.record',
|
|
|
|
- success:()=>{
|
|
|
|
- this.startRecordManage();
|
|
|
|
- },
|
|
|
|
- fail:err=>{
|
|
|
|
- uni.showModal({
|
|
|
|
- content: '检测到您没打开录音功能权限,是否去设置打开?',
|
|
|
|
- confirmText: "确认",
|
|
|
|
- cancelText: '取消',
|
|
|
|
- success:res=>{
|
|
|
|
- if(res.confirm){
|
|
|
|
- uni.openSetting({
|
|
|
|
- success:ress=>{
|
|
|
|
- if(ress.authSetting){
|
|
|
|
- this.startRecordManage();
|
|
|
|
- }
|
|
|
|
|
|
+ return obj
|
|
|
|
+ // [{,'margin-top':`${topbarOffsetHeight}px`}]
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ uni.$on('videoPlayerHandler', value => {
|
|
|
|
+ this.videoPlay = value.isPlay;
|
|
|
|
+ this.videoMessage = value.message;
|
|
|
|
+ });
|
|
|
|
+ uni.authorize({
|
|
|
|
+ scope: 'scope.record',
|
|
|
|
+ success: () => {
|
|
|
|
+ this.startRecordManage();
|
|
|
|
+ },
|
|
|
|
+ fail: err => {
|
|
|
|
+ uni.showModal({
|
|
|
|
+ content: '检测到您没打开录音功能权限,是否去设置打开?',
|
|
|
|
+ confirmText: "确认",
|
|
|
|
+ cancelText: '取消',
|
|
|
|
+ success: res => {
|
|
|
|
+ if (res.confirm) {
|
|
|
|
+ uni.openSetting({
|
|
|
|
+ success: ress => {
|
|
|
|
+ if (ress.authSetting) {
|
|
|
|
+ this.startRecordManage();
|
|
}
|
|
}
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ })
|
|
}
|
|
}
|
|
- })
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ onLoad(options) {
|
|
|
|
+ this.conversationID = options.conversationid;
|
|
|
|
+ uni.$TUIKit.setMessageRead({
|
|
|
|
+ conversationID: this.conversationID
|
|
|
|
+ })
|
|
|
|
+ uni.$TUIKit.getConversationProfile(this.conversationID).then(res => {
|
|
|
|
+ const { conversation } = res.data;
|
|
|
|
+ this.conversation = conversation;
|
|
|
|
+ console.log(this.conversation)
|
|
|
|
+ });
|
|
|
|
+ let pages = getCurrentPages();
|
|
|
|
+ let prePage = pages[pages.length - 2];
|
|
|
|
+ this.userInfo = prePage.$vm.userInfo;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+
|
|
|
|
+ if (this.userInfo.lastActiveTime === 0 || this.userInfo.online) {
|
|
|
|
+ this.onlineState = '在线';
|
|
|
|
+ }
|
|
|
|
+ else if (this.userInfo.lastActiveTime < 30 && !this.userInfo.online) {
|
|
|
|
+ this.onlineState = '刚刚';
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.onlineState = '离线';
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.computedScollviewHeight();
|
|
|
|
+ }, 500)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ inputBindFocus(e) {
|
|
|
|
+ // 获取手机键盘的高度,赋值给input 所在盒子的 bottom 值
|
|
|
|
+ // 注意!!! 这里的 px 至关重要!!! 我搜到的很多解决方案都没有说这里要添加 px
|
|
|
|
+ // this.$emit('changeBottomVal', e.detail.height + 'px')
|
|
|
|
+ this.scrollHeight = e.detail.height
|
|
|
|
+ this.bottomVal = e.detail.height
|
|
|
|
+ console.log(e.detail.height, 'e.detail.height', e, 'this.scrollHeight', this.scrollHeight)
|
|
},
|
|
},
|
|
- onLoad(options) {
|
|
|
|
- this.conversationID=options.conversationid;
|
|
|
|
- uni.$TUIKit.setMessageRead({
|
|
|
|
- conversationID:this.conversationID
|
|
|
|
|
|
+
|
|
|
|
+ inputBindBlur() {
|
|
|
|
+ // input 失去焦点,键盘隐藏,设置 input 所在盒子的 bottom 值为0
|
|
|
|
+ // this.$emit('changeBottomVal', 0)
|
|
|
|
+ this.scrollHeight = 0
|
|
|
|
+ this.bottomVal = 0
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ back() {
|
|
|
|
+ uni.navigateBack({
|
|
|
|
+ delta: 1
|
|
})
|
|
})
|
|
- uni.$TUIKit.getConversationProfile(this.conversationID).then(res => {
|
|
|
|
- const { conversation } = res.data;
|
|
|
|
- this.conversation = conversation;
|
|
|
|
- console.log(this.conversation)
|
|
|
|
|
|
+ },
|
|
|
|
+ prevent() {
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ stopVideoHander() {
|
|
|
|
+ this.videoPlay = false;
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 计算scroll高度
|
|
|
|
+ */
|
|
|
|
+ computedScollviewHeight() {
|
|
|
|
+ let query = uni.createSelectorQuery().in(this);
|
|
|
|
+ let heightLeaf = 0;
|
|
|
|
+ query.selectAll('#topnav,#talk-box').boundingClientRect(data => {
|
|
|
|
+ data.forEach(item => {
|
|
|
|
+ heightLeaf += item.height;
|
|
|
|
+ })
|
|
|
|
+ }).exec(() => {
|
|
|
|
+ let sysInfo = uni.getSystemInfoSync();
|
|
|
|
+ this.scrollHeight = sysInfo.windowHeight - heightLeaf;
|
|
|
|
+ this.$refs.messageList.scrollToButtom();
|
|
});
|
|
});
|
|
- let pages=getCurrentPages();
|
|
|
|
- let prePage=pages[pages.length-2];
|
|
|
|
- this.userInfo=prePage.$vm.userInfo;
|
|
|
|
-
|
|
|
|
|
|
+
|
|
},
|
|
},
|
|
- mounted() {
|
|
|
|
-
|
|
|
|
- if(this.userInfo.lastActiveTime===0||this.userInfo.online){
|
|
|
|
- this.onlineState='在线';
|
|
|
|
- }
|
|
|
|
- else if(this.userInfo.lastActiveTime<30&&!this.userInfo.online){
|
|
|
|
- this.onlineState='刚刚';
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 推荐下拉刷新、加载更多
|
|
|
|
+ */
|
|
|
|
+ scrollRefresh() {
|
|
|
|
+ if (this.scrollRefreshing) {
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- else{
|
|
|
|
- this.onlineState='离线';
|
|
|
|
- }
|
|
|
|
- setTimeout(()=>{
|
|
|
|
- this.computedScollviewHeight();
|
|
|
|
- },500)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ this.scrollRefreshing = true;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.scrollTriggered = false;
|
|
|
|
+ this.scrollRefreshing = false;
|
|
|
|
+ }, 1000);
|
|
|
|
+ this.isLoadPreData = true;
|
|
|
|
+
|
|
},
|
|
},
|
|
- methods: {
|
|
|
|
- back(){
|
|
|
|
- uni.navigateBack({
|
|
|
|
- delta:1
|
|
|
|
- })
|
|
|
|
- },
|
|
|
|
- prevent(){
|
|
|
|
- return false;
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- stopVideoHander() {
|
|
|
|
- this.videoPlay = false;
|
|
|
|
- },
|
|
|
|
- /**
|
|
|
|
- * 计算scroll高度
|
|
|
|
- */
|
|
|
|
- computedScollviewHeight() {
|
|
|
|
- let query = uni.createSelectorQuery().in(this);
|
|
|
|
- let heightLeaf =0;
|
|
|
|
- query.selectAll('#topnav,#talk-box').boundingClientRect(data => {
|
|
|
|
- data.forEach(item=>{
|
|
|
|
- heightLeaf+=item.height;
|
|
|
|
- })
|
|
|
|
- }).exec(() => {
|
|
|
|
- let sysInfo = uni.getSystemInfoSync();
|
|
|
|
- this.scrollHeight = sysInfo.windowHeight - heightLeaf;
|
|
|
|
- this.$refs.messageList.scrollToButtom();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- },
|
|
|
|
- /**
|
|
|
|
- * 推荐下拉刷新、加载更多
|
|
|
|
- */
|
|
|
|
- scrollRefresh(){
|
|
|
|
- if (this.scrollRefreshing)
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- this.scrollRefreshing = true;
|
|
|
|
|
|
+ scrollPulling(e) { },
|
|
|
|
+ scrollRestore() { this.scrollTriggered = true; },
|
|
|
|
+ scrollAbort() { },
|
|
|
|
+ scrollToBottom() { },
|
|
|
|
+ showActionPanel(index) {
|
|
|
|
+ if (this.showActionIndex === index) {
|
|
|
|
+ this.showActionIndex = -1;
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
- this.scrollTriggered = false;
|
|
|
|
- this.scrollRefreshing = false;
|
|
|
|
- }, 1000);
|
|
|
|
- this.isLoadPreData=true;
|
|
|
|
-
|
|
|
|
- },
|
|
|
|
- scrollPulling(e) {},
|
|
|
|
- scrollRestore() {this.scrollTriggered = true;},
|
|
|
|
- scrollAbort() {},
|
|
|
|
- scrollToBottom(){},
|
|
|
|
- showActionPanel(index){
|
|
|
|
- if(this.showActionIndex===index){
|
|
|
|
- this.showActionIndex=-1;
|
|
|
|
- setTimeout(()=>{
|
|
|
|
|
|
+ this.computedScollviewHeight();
|
|
|
|
+ }, 50)
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (index) {
|
|
|
|
+ case 0:
|
|
|
|
+ this.showActionIndex = index;
|
|
|
|
+ setTimeout(() => {
|
|
this.computedScollviewHeight();
|
|
this.computedScollviewHeight();
|
|
- },50)
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch(index){
|
|
|
|
- case 0:
|
|
|
|
- this.showActionIndex=index;
|
|
|
|
- setTimeout(()=>{
|
|
|
|
- this.computedScollviewHeight();
|
|
|
|
- },50)
|
|
|
|
- break;
|
|
|
|
- case 1:
|
|
|
|
- this.showActionIndex=-1;
|
|
|
|
- uni.chooseImage({
|
|
|
|
- count: 1,
|
|
|
|
- sizeType: ['original', 'compressed'],
|
|
|
|
- sourceType: ['album', 'camera'],
|
|
|
|
- success:res=>{
|
|
|
|
- console.log(res)
|
|
|
|
- const message = uni.$TUIKit.createImageMessage({
|
|
|
|
- to: String(this.userInfo.id),
|
|
|
|
- conversationType: this.conversation.type,
|
|
|
|
- payload: {
|
|
|
|
- file: res
|
|
|
|
- },
|
|
|
|
- onProgress:event=>{}
|
|
|
|
- });
|
|
|
|
- this.$sendTIMMessage(message);
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- break;
|
|
|
|
- case 2:
|
|
|
|
- uni.chooseVideo({
|
|
|
|
- sourceType: ['album', 'camera'],
|
|
|
|
- maxDuration: 60,
|
|
|
|
- camera: 'back',
|
|
|
|
- success:res=>{
|
|
|
|
- const message = uni.$TUIKit.createVideoMessage({
|
|
|
|
- to: String(this.userInfo.id),
|
|
|
|
- conversationType: this.conversation.type,
|
|
|
|
- payload: {
|
|
|
|
- file: res
|
|
|
|
- },
|
|
|
|
- onProgress:event=>{}
|
|
|
|
- });
|
|
|
|
- this.$sendTIMMessage(message);
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ }, 50)
|
|
break;
|
|
break;
|
|
- case 3:
|
|
|
|
- this.showActionIndex=index;
|
|
|
|
- setTimeout(()=>{
|
|
|
|
- this.computedScollviewHeight();
|
|
|
|
- },50)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- },
|
|
|
|
- appendMessage(e) {
|
|
|
|
- this.inputText+=e.detail.message;
|
|
|
|
- },
|
|
|
|
- startRecordManage(){
|
|
|
|
- // 加载声音录制管理器
|
|
|
|
- this.recorderManager = uni.getRecorderManager();
|
|
|
|
- console.log(this.recorderManager)
|
|
|
|
- this.recorderManager.onStop(res => {
|
|
|
|
- console.log(res)
|
|
|
|
- clearInterval(this.recordTimer);
|
|
|
|
- // 兼容 uniapp 打包app,duration 和 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'
|
|
|
|
|
|
+ case 1:
|
|
|
|
+ this.showActionIndex = -1;
|
|
|
|
+ uni.chooseImage({
|
|
|
|
+ count: 1,
|
|
|
|
+ sizeType: ['original', 'compressed'],
|
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
|
+ success: res => {
|
|
|
|
+ console.log(res)
|
|
|
|
+ const message = uni.$TUIKit.createImageMessage({
|
|
|
|
+ to: String(this.userInfo.id),
|
|
|
|
+ conversationType: this.conversation.type,
|
|
|
|
+ payload: {
|
|
|
|
+ file: res
|
|
|
|
+ },
|
|
|
|
+ onProgress: event => { }
|
|
});
|
|
});
|
|
- } else {
|
|
|
|
- // res.tempFilePath 存储录音文件的临时路径
|
|
|
|
- const message = uni.$TUIKit.createAudioMessage({
|
|
|
|
|
|
+ this.$sendTIMMessage(message);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ uni.chooseVideo({
|
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
|
+ maxDuration: 60,
|
|
|
|
+ camera: 'back',
|
|
|
|
+ success: res => {
|
|
|
|
+ const message = uni.$TUIKit.createVideoMessage({
|
|
to: String(this.userInfo.id),
|
|
to: String(this.userInfo.id),
|
|
conversationType: this.conversation.type,
|
|
conversationType: this.conversation.type,
|
|
payload: {
|
|
payload: {
|
|
- file: msg
|
|
|
|
- }
|
|
|
|
|
|
+ file: res
|
|
|
|
+ },
|
|
|
|
+ onProgress: event => { }
|
|
});
|
|
});
|
|
this.$sendTIMMessage(message);
|
|
this.$sendTIMMessage(message);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- this.startPoint=0;
|
|
|
|
- this.isRecording=false;
|
|
|
|
- this.canSend=true;
|
|
|
|
- this.voiceText='按住说话,松手发送';
|
|
|
|
- });
|
|
|
|
- this.recorderManager.onError(err=>{
|
|
|
|
- console.log(err)
|
|
|
|
- })
|
|
|
|
- },
|
|
|
|
- handleLongPress(e) {
|
|
|
|
- uni.vibrateShort();
|
|
|
|
- this.recorderManager.start({
|
|
|
|
- duration: 60000,
|
|
|
|
- // 录音的时长,单位 ms,最大值 600000(10 分钟)
|
|
|
|
- sampleRate: 44100,
|
|
|
|
- // 采样率
|
|
|
|
- numberOfChannels: 1,
|
|
|
|
- // 录音通道数
|
|
|
|
- encodeBitRate: 192000,
|
|
|
|
- // 编码码率
|
|
|
|
- format: 'aac' // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和Web)互通
|
|
|
|
- });
|
|
|
|
- this.startPoint=e.touches[0];
|
|
|
|
- this.voiceText='正在录音,上划可取消';
|
|
|
|
- this.isRecording=true;
|
|
|
|
- this.recordTime=0;
|
|
|
|
- this.recordTimer = setInterval(() => {
|
|
|
|
- this.recordTime++;
|
|
|
|
- if(this.recorTime>=this.recordTimeTotal){
|
|
|
|
- this.recorderManager.stop();
|
|
|
|
- clearInterval(this.recordTimer);
|
|
|
|
- this.recordTimer=null;
|
|
|
|
- }
|
|
|
|
- }, 1000);
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- // 录音时的手势上划移动距离对应文案变化
|
|
|
|
- handleTouchMove(e) {
|
|
|
|
- if (this.isRecording) {
|
|
|
|
- if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) {
|
|
|
|
- this.voiceText='松开手指,取消发送';
|
|
|
|
- this.canSend=false;
|
|
|
|
- } else if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) {
|
|
|
|
- this.voiceText='上划可取消';
|
|
|
|
- this.canSend=true;
|
|
|
|
|
|
+ })
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ this.showActionIndex = index;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.computedScollviewHeight();
|
|
|
|
+ }, 50)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ appendMessage(e) {
|
|
|
|
+ this.inputText += e.detail.message;
|
|
|
|
+ },
|
|
|
|
+ startRecordManage() {
|
|
|
|
+ // 加载声音录制管理器
|
|
|
|
+ this.recorderManager = uni.getRecorderManager();
|
|
|
|
+ console.log(this.recorderManager)
|
|
|
|
+ this.recorderManager.onStop(res => {
|
|
|
|
+ console.log(res)
|
|
|
|
+ clearInterval(this.recordTimer);
|
|
|
|
+ // 兼容 uniapp 打包app,duration 和 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 {
|
|
} else {
|
|
- this.voiceText='抬起停止';
|
|
|
|
- this.canSend=true;
|
|
|
|
|
|
+ // res.tempFilePath 存储录音文件的临时路径
|
|
|
|
+ const message = uni.$TUIKit.createAudioMessage({
|
|
|
|
+ to: String(this.userInfo.id),
|
|
|
|
+ conversationType: this.conversation.type,
|
|
|
|
+ payload: {
|
|
|
|
+ file: msg
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ this.$sendTIMMessage(message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- },
|
|
|
|
-
|
|
|
|
- // 手指离开页面滑动
|
|
|
|
- handleTouchEnd() {
|
|
|
|
- this.isRecording=false;
|
|
|
|
- this.voiceText='按住说话,松手发送';
|
|
|
|
- uni.hideLoading();
|
|
|
|
- this.recorderManager.stop();
|
|
|
|
- },
|
|
|
|
- sendTextMessage() {
|
|
|
|
- const to = String(this.userInfo.id);
|
|
|
|
- const text =this.inputText;
|
|
|
|
- const message = uni.$TUIKit.createTextMessage({
|
|
|
|
- to,
|
|
|
|
- conversationType: this.conversation.type,
|
|
|
|
- payload: {
|
|
|
|
- text
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- this.inputText='';
|
|
|
|
- this.$sendTIMMessage(message);
|
|
|
|
- },
|
|
|
|
- $sendTIMMessage(message) {
|
|
|
|
-
|
|
|
|
- uni.$TUIKit.sendMessage(message).then((res) => {
|
|
|
|
- this.$EventBus.$emit('sendMessage', message)
|
|
|
|
- this.$refs.messageList.scrollToButtom();
|
|
|
|
- }).catch((error) => {
|
|
|
|
- uni.showToast({
|
|
|
|
- title:'发送消息失败',
|
|
|
|
- icon:"none"
|
|
|
|
- })
|
|
|
|
|
|
+ this.startPoint = 0;
|
|
|
|
+ this.isRecording = false;
|
|
|
|
+ this.canSend = true;
|
|
|
|
+ this.voiceText = '按住说话,松手发送';
|
|
|
|
+ });
|
|
|
|
+ this.recorderManager.onError(err => {
|
|
|
|
+ console.log(err)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ handleLongPress(e) {
|
|
|
|
+ uni.vibrateShort();
|
|
|
|
+ this.recorderManager.start({
|
|
|
|
+ duration: 60000,
|
|
|
|
+ // 录音的时长,单位 ms,最大值 600000(10 分钟)
|
|
|
|
+ sampleRate: 44100,
|
|
|
|
+ // 采样率
|
|
|
|
+ numberOfChannels: 1,
|
|
|
|
+ // 录音通道数
|
|
|
|
+ encodeBitRate: 192000,
|
|
|
|
+ // 编码码率
|
|
|
|
+ format: 'aac' // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和Web)互通
|
|
|
|
+ });
|
|
|
|
+ this.startPoint = e.touches[0];
|
|
|
|
+ this.voiceText = '正在录音,上划可取消';
|
|
|
|
+ this.isRecording = true;
|
|
|
|
+ this.recordTime = 0;
|
|
|
|
+ this.recordTimer = setInterval(() => {
|
|
|
|
+ this.recordTime++;
|
|
|
|
+ if (this.recorTime >= this.recordTimeTotal) {
|
|
|
|
+ this.recorderManager.stop();
|
|
|
|
+ clearInterval(this.recordTimer);
|
|
|
|
+ this.recordTimer = null;
|
|
|
|
+ }
|
|
|
|
+ }, 1000);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 录音时的手势上划移动距离对应文案变化
|
|
|
|
+ handleTouchMove(e) {
|
|
|
|
+ if (this.isRecording) {
|
|
|
|
+ if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) {
|
|
|
|
+ this.voiceText = '松开手指,取消发送';
|
|
|
|
+ this.canSend = false;
|
|
|
|
+ } else if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) {
|
|
|
|
+ this.voiceText = '上划可取消';
|
|
|
|
+ this.canSend = true;
|
|
|
|
+ } else {
|
|
|
|
+ this.voiceText = '抬起停止';
|
|
|
|
+ this.canSend = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 手指离开页面滑动
|
|
|
|
+ handleTouchEnd() {
|
|
|
|
+ this.isRecording = false;
|
|
|
|
+ this.voiceText = '按住说话,松手发送';
|
|
|
|
+ uni.hideLoading();
|
|
|
|
+ this.recorderManager.stop();
|
|
|
|
+ },
|
|
|
|
+ sendTextMessage() {
|
|
|
|
+ const to = String(this.userInfo.id);
|
|
|
|
+ const text = this.inputText;
|
|
|
|
+ const message = uni.$TUIKit.createTextMessage({
|
|
|
|
+ to,
|
|
|
|
+ conversationType: this.conversation.type,
|
|
|
|
+ payload: {
|
|
|
|
+ text
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ this.inputText = '';
|
|
|
|
+ this.$sendTIMMessage(message);
|
|
|
|
+ },
|
|
|
|
+ $sendTIMMessage(message) {
|
|
|
|
+
|
|
|
|
+ uni.$TUIKit.sendMessage(message).then((res) => {
|
|
|
|
+ this.$EventBus.$emit('sendMessage', message)
|
|
|
|
+ this.$refs.messageList.scrollToButtom();
|
|
|
|
+ }).catch((error) => {
|
|
|
|
+ uni.showToast({
|
|
|
|
+ title: '发送消息失败',
|
|
|
|
+ icon: "none"
|
|
})
|
|
})
|
|
- },
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
-.container{
|
|
|
|
|
|
+.container {
|
|
width: 100vw;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
height: 100vh;
|
|
background-color: $bgcolor1;
|
|
background-color: $bgcolor1;
|
|
position: relative;
|
|
position: relative;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
|
+
|
|
.topnav {
|
|
.topnav {
|
|
padding: 0 10rpx;
|
|
padding: 0 10rpx;
|
|
position: fixed;
|
|
position: fixed;
|
|
@@ -421,51 +444,59 @@
|
|
width: 100vw;
|
|
width: 100vw;
|
|
z-index: 100;
|
|
z-index: 100;
|
|
background-color: $bgcolor1;
|
|
background-color: $bgcolor1;
|
|
- .nav-item{
|
|
|
|
|
|
+
|
|
|
|
+ .nav-item {
|
|
width: 40rpx;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
height: 40rpx;
|
|
margin-left: 16rpx;
|
|
margin-left: 16rpx;
|
|
-
|
|
|
|
- .nav-img{
|
|
|
|
|
|
+
|
|
|
|
+ .nav-img {
|
|
width: 40rpx;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
height: 40rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- .nav-center{
|
|
|
|
|
|
+
|
|
|
|
+ .nav-center {
|
|
flex: 1;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
- .nav-text{
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ .nav-text {
|
|
|
|
+
|
|
color: $fontcolor5;
|
|
color: $fontcolor5;
|
|
height: 40rpx;
|
|
height: 40rpx;
|
|
text-align: center;
|
|
text-align: center;
|
|
}
|
|
}
|
|
- .nav-tip{
|
|
|
|
- color:$fontcolor2;
|
|
|
|
|
|
+
|
|
|
|
+ .nav-tip {
|
|
|
|
+ color: $fontcolor2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
- .talk-box{
|
|
|
|
|
|
+
|
|
|
|
+ .talk-box {
|
|
position: fixed;
|
|
position: fixed;
|
|
bottom: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
width: 100vw;
|
|
padding-top: 16rpx;
|
|
padding-top: 16rpx;
|
|
background-color: $bgcolor1;
|
|
background-color: $bgcolor1;
|
|
- .input-box{
|
|
|
|
|
|
+
|
|
|
|
+ .input-box {
|
|
margin: 0rpx 32rpx;
|
|
margin: 0rpx 32rpx;
|
|
height: 80rpx;
|
|
height: 80rpx;
|
|
border-radius: 80rpx;
|
|
border-radius: 80rpx;
|
|
background-color: $bgcolor4;
|
|
background-color: $bgcolor4;
|
|
padding: 0 24rpx;
|
|
padding: 0 24rpx;
|
|
- .input{
|
|
|
|
|
|
+
|
|
|
|
+ .input {
|
|
width: 100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
height: 100%;
|
|
color: #ffffff;
|
|
color: #ffffff;
|
|
font-size: 22rpx;
|
|
font-size: 22rpx;
|
|
}
|
|
}
|
|
- .input-btn{
|
|
|
|
|
|
+
|
|
|
|
+ .input-btn {
|
|
background-color: $primary;
|
|
background-color: $primary;
|
|
color: #ffffff;
|
|
color: #ffffff;
|
|
border-radius: 16rpx;
|
|
border-radius: 16rpx;
|
|
@@ -473,52 +504,62 @@
|
|
line-height: 56rpx;
|
|
line-height: 56rpx;
|
|
width: 120rpx;
|
|
width: 120rpx;
|
|
text-align: center;
|
|
text-align: center;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- .action-box{
|
|
|
|
|
|
+
|
|
|
|
+ .action-box {
|
|
padding: 0rpx 0rpx 20rpx 0rpx;
|
|
padding: 0rpx 0rpx 20rpx 0rpx;
|
|
margin: 0 90rpx;
|
|
margin: 0 90rpx;
|
|
margin-top: 36rpx;
|
|
margin-top: 36rpx;
|
|
- .act-img{
|
|
|
|
|
|
+
|
|
|
|
+ .act-img {
|
|
width: 56rpx;
|
|
width: 56rpx;
|
|
height: 56rpx;
|
|
height: 56rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- .action-panel{
|
|
|
|
|
|
+
|
|
|
|
+ .action-panel {
|
|
width: 100vw;
|
|
width: 100vw;
|
|
- .voice-panel{
|
|
|
|
|
|
+
|
|
|
|
+ .voice-panel {
|
|
height: 400rpx;
|
|
height: 400rpx;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
- .voice-text{
|
|
|
|
|
|
+
|
|
|
|
+ .voice-text {
|
|
color: #7D7DA4;
|
|
color: #7D7DA4;
|
|
text-align: center;
|
|
text-align: center;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
- .voice-img{
|
|
|
|
|
|
+
|
|
|
|
+ .voice-img {
|
|
width: 200rpx;
|
|
width: 200rpx;
|
|
height: 200rpx;
|
|
height: 200rpx;
|
|
margin-top: 40rpx;
|
|
margin-top: 40rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- .emoji-box{
|
|
|
|
|
|
+
|
|
|
|
+ .emoji-box {
|
|
padding: 0 11rpx;
|
|
padding: 0 11rpx;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
height: 400rpx;
|
|
height: 400rpx;
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|
|
transition: height .3s;
|
|
transition: height .3s;
|
|
- .emoji-item{
|
|
|
|
|
|
+
|
|
|
|
+ .emoji-item {
|
|
width: 64rpx;
|
|
width: 64rpx;
|
|
height: 64rpx;
|
|
height: 64rpx;
|
|
padding: 20rpx;
|
|
padding: 20rpx;
|
|
- .emoji-img{
|
|
|
|
|
|
+
|
|
|
|
+ .emoji-img {
|
|
width: 64rpx;
|
|
width: 64rpx;
|
|
height: 64rpx;
|
|
height: 64rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
.container-box {
|
|
.container-box {
|
|
position: fixed;
|
|
position: fixed;
|
|
display: flex;
|
|
display: flex;
|
|
@@ -529,11 +570,11 @@
|
|
bottom: 0;
|
|
bottom: 0;
|
|
top: 0;
|
|
top: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
+
|
|
.video-message {
|
|
.video-message {
|
|
width: 90vw;
|
|
width: 90vw;
|
|
height: auto;
|
|
height: auto;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
-</style>
|
|
|
|
|
|
+}</style>
|
|
|
|
|