1583 lines
46 KiB
Plaintext
1583 lines
46 KiB
Plaintext
<style lang="less" scoped>
|
|
@import url(../../styles/theme.less);
|
|
page {
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.m_tips_icon {
|
|
width: 140rpx;
|
|
height: 140rpx;
|
|
position: fixed;
|
|
top: 32rpx;
|
|
right: -4rpx;
|
|
z-index: 999;
|
|
}
|
|
|
|
.ui-scroll-view{
|
|
-webkit-overflow-scrolling: touch;
|
|
will-change: transform;
|
|
background: #f2f2f2;
|
|
}
|
|
|
|
.ui-top-placeholder {
|
|
width: 100vw;
|
|
height: 30rpx;
|
|
}
|
|
|
|
.ui-tips-pic{
|
|
width: 76%;
|
|
height: 62rpx;
|
|
border-radius: 16rpx;
|
|
margin: 0 0 10rpx 50rpx;
|
|
}
|
|
|
|
.ui-tips-box{
|
|
display: inline-block;
|
|
padding: 20rpx;
|
|
border-radius: 16rpx;
|
|
width: 76%;
|
|
margin: 0 50rpx 30rpx 50rpx;
|
|
background: #ffffff;
|
|
.ui-tips_icon{
|
|
width: 28rpx;
|
|
height: 28rpx;
|
|
vertical-align: middle;
|
|
margin-top: -8rpx;
|
|
margin-right: 6rpx;
|
|
}
|
|
.ui-tips_text{
|
|
text-align: justify;
|
|
text-align-last: left;
|
|
line-height: 1.6;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
|
|
.ui-msg-data-box {
|
|
padding: 0 30rpx 160rpx 30rpx;
|
|
|
|
.ui-msg-data {
|
|
overflow: hidden;
|
|
padding-bottom: 36rpx;
|
|
}
|
|
|
|
.ui-left-msg-box {
|
|
float: left;
|
|
}
|
|
|
|
.ui-right-msg-box {
|
|
float: right;
|
|
}
|
|
|
|
.ui-error-icon, .ui-error-icon-v2{
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: -50rpx;
|
|
transform: translateY(-50%);
|
|
}
|
|
|
|
.ui-error-icon-v2{
|
|
left: initial;
|
|
right: -60rpx
|
|
}
|
|
|
|
.ui-user-pic {
|
|
width: 86rpx;
|
|
height: 86rpx;
|
|
border: 2rpx solid #eaeaea;
|
|
box-shadow: 0 0 12rpx #cccccc;
|
|
border-radius: 50%;
|
|
display: block;
|
|
vertical-align: top;
|
|
}
|
|
|
|
.ui-user-name {
|
|
color: #86889a;
|
|
letter-spacing: 2rpx;
|
|
}
|
|
|
|
.ui-msg-left,
|
|
.ui-msg-right {
|
|
max-width: 480rpx;
|
|
padding: 20rpx 24rpx;
|
|
background: #ffffff;
|
|
line-height: 42rpx;
|
|
letter-spacing: 2rpx;
|
|
word-wrap: break-word;
|
|
word-break: break-all;
|
|
|
|
.emoji_small {
|
|
width: 42rpx;
|
|
height: 42rpx;
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
|
|
.ui-msg-left-pic, .ui-msg-right-pic{
|
|
max-width: 200rpx;
|
|
max-height: 200rpx;
|
|
border-radius: 20rpx;
|
|
display: block;
|
|
vertical-align: top;
|
|
}
|
|
.ui-right-audio{
|
|
background: #ff7d9f;
|
|
}
|
|
|
|
.ui-left-audio{
|
|
background: #ffffff;
|
|
}
|
|
|
|
.ui-audio-box{
|
|
padding: 10rpx 24rpx;
|
|
box-sizing: content-box;
|
|
height: 100%;
|
|
justify-content: space-between;
|
|
overflow-x: hidden;
|
|
|
|
.ui-audio-icon,.ui-audio-icon-l-play,.ui-audio-icon-r-play{
|
|
position: relative;
|
|
width: 28rpx;
|
|
height: 36rpx;
|
|
overflow: hidden;
|
|
}
|
|
.ui-audio-icon-l-play:before,.ui-audio-icon-r-play:before{
|
|
content: '';
|
|
position: absolute;
|
|
top:0;
|
|
width: 28rpx;
|
|
height: 36rpx;
|
|
}
|
|
.ui-audio-icon-l-play:before {
|
|
left: 0;
|
|
background: #ffffff;
|
|
animation: volumeLPlay 1.5s linear infinite;
|
|
}
|
|
.ui-audio-icon-r-play:before{
|
|
right:0;
|
|
background: #ff7d9f;
|
|
animation: volumeRPlay 1.5s linear infinite;
|
|
}
|
|
@keyframes volumeLPlay{
|
|
0%{
|
|
left: 8rpx;
|
|
}
|
|
25%{
|
|
left: 8rpx;
|
|
}
|
|
50%{
|
|
left: 20rpx;
|
|
}
|
|
75%{
|
|
left: 28rpx;
|
|
}
|
|
100%{
|
|
left: 28rpx;
|
|
}
|
|
}
|
|
@keyframes volumeRPlay{
|
|
0%{
|
|
right: 8rpx;
|
|
}
|
|
25%{
|
|
right: 8rpx;
|
|
}
|
|
50%{
|
|
right: 20rpx;
|
|
}
|
|
75%{
|
|
right: 28rpx;
|
|
}
|
|
100%{
|
|
right: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.liveImg {
|
|
position: relative;
|
|
border-radius: 20rpx;
|
|
.ui-video-box, .ui-video-r-box{
|
|
position: relative;
|
|
.ui-vide-poster{
|
|
position: absolute;
|
|
top:50%;
|
|
left:50%;
|
|
transform: translate(-50%,-50%);
|
|
text-align: center;
|
|
}
|
|
.ui-video_play_icon{
|
|
width: 52rpx;
|
|
height:52rpx;
|
|
}
|
|
.ui-video_play-text{
|
|
width: 120rpx;
|
|
}
|
|
}
|
|
.ui-video-box{
|
|
width: auto;
|
|
border-radius: 16rpx;
|
|
}
|
|
.ui-video-r-box{
|
|
width: auto;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
|
|
.ui-source-text {
|
|
width: fit-content;
|
|
border-radius: 0 8rpx 8rpx 0;
|
|
background: linear-gradient(90deg, rgba(221, 216, 250, 0.14) 0%, rgba(221, 216, 250, 1) 100%);
|
|
padding: 4rpx 16rpx 4rpx 36rpx;
|
|
margin-top: 10rpx;
|
|
float: right;
|
|
}
|
|
|
|
.ui-msg-right {
|
|
background: #FF7D9F;
|
|
}
|
|
|
|
.ui-copy-icon-box {
|
|
width: 54rpx;
|
|
height: 54rpx;
|
|
background: #ffffff;
|
|
border-radius: 50%;
|
|
position: absolute;
|
|
right: -70rpx;
|
|
top: 0;
|
|
|
|
.ui-copy-icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
}
|
|
|
|
.ui-left-msg-radius {
|
|
border-radius: 0 32rpx 32rpx 32rpx;
|
|
}
|
|
|
|
.ui-right-msg-radius {
|
|
border-radius: 32rpx 0 32rpx 32rpx;
|
|
}
|
|
}
|
|
|
|
.ui-bottom-input-box {
|
|
width: 100vw;
|
|
padding: 32rpx 30rpx 72rpx 30rpx;
|
|
box-sizing: border-box;
|
|
background: #ffffff;
|
|
border-radius: 42rpx 42rpx 0 0;
|
|
box-shadow: 0 0 12rpx #f8f8f8;
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
z-index: 999;
|
|
|
|
.replyView{
|
|
width: 100vw;
|
|
position: fixed;
|
|
bottom: 180rpx;
|
|
left: 0;
|
|
padding: 32rpx;
|
|
z-index: 9999999;
|
|
|
|
.replyContent{
|
|
border-radius: 32rpx;
|
|
max-height: 78vh;
|
|
overflow: auto;
|
|
padding: 16rpx 26rpx;
|
|
background: #FFFFFF;
|
|
line-height: 42rpx;
|
|
letter-spacing: 4rpx;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.main-content-box {
|
|
display: inline-block;
|
|
white-space: pre-line;
|
|
vertical-align: center;
|
|
align-items: center;
|
|
margin-top: 4rpx;
|
|
word-break: break-all; // 纯数字、单词换行
|
|
|
|
.m_rich {
|
|
margin-right: -4rpx;
|
|
}
|
|
|
|
.emoji_text {
|
|
align-items: center;
|
|
padding: 4rpx;
|
|
line-height: 40rpx;
|
|
|
|
.emoji_small {
|
|
width: 42rpx;
|
|
height: 42rpx;
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.ui-input-box {
|
|
width: 85vw;
|
|
height: 72rpx;
|
|
line-height: 72rpx;
|
|
padding: 20rpx 76rpx 20rpx 26rpx;
|
|
margin-right: 20rpx;
|
|
background: #f5f5f7;
|
|
border-radius: 100rpx;
|
|
position: relative;
|
|
|
|
.ui-emoji-icon{
|
|
width: 44rpx;
|
|
height: 44rpx;
|
|
position: absolute;
|
|
right: 20rpx;
|
|
z-index: 9;
|
|
}
|
|
|
|
.ui-input {
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 3;
|
|
background: initial;
|
|
word-break: break-all;
|
|
}
|
|
}
|
|
|
|
.ui-send-box {
|
|
.ui-send-icon{
|
|
width: 0;
|
|
height: 66rpx;
|
|
transition: width .2s;
|
|
transition-timing-function: linear;
|
|
}
|
|
.ui-send-icon.active {
|
|
width: 90rpx;
|
|
height: 90rpx;
|
|
color: white;
|
|
border-radius: 12rpx;
|
|
}
|
|
.ui_add_icon{
|
|
width: 44rpx;
|
|
height: 44rpx;
|
|
transition-delay: .2s;
|
|
}
|
|
.ui_add_icon.active {
|
|
width: 0;
|
|
height: 44rpx;
|
|
transition-delay: 0s;
|
|
}
|
|
}
|
|
|
|
.ui-microphone-box{
|
|
margin-right: 20rpx;
|
|
width: 36rpx;
|
|
height: 44rpx;
|
|
.ui-microphone-image{
|
|
width: 36rpx;
|
|
height: 44rpx;
|
|
}
|
|
}
|
|
.ui-microphone-close,
|
|
.ui-microphone-open{
|
|
width: 100%;
|
|
text-align: center;
|
|
height: 72rpx;
|
|
line-height: 72rpx;
|
|
border-radius: 36rpx;
|
|
}
|
|
.ui-microphone-open{
|
|
background: #FFFFFF;
|
|
border: 2rpx solid #E8E8E8;
|
|
}
|
|
.ui-microphone-close{
|
|
background: #E8E8E8;
|
|
}
|
|
|
|
.ui-microphone-message{
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%,-50%);
|
|
width: 320rpx;
|
|
height: 320rpx;
|
|
background: #757575;
|
|
border-radius: 24rpx;
|
|
text-align: center;
|
|
.ui-icon-change-stop .ui-icon-change:before{
|
|
animation-play-state: paused!important;
|
|
}
|
|
.ui-icon-box{
|
|
margin:86rpx 0 0 88rpx;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
.ui-icon-microphone{
|
|
margin-right: 20rpx;
|
|
width: 76rpx;
|
|
height: 110rpx;
|
|
}
|
|
.ui-icon-change{
|
|
margin-bottom: 12rpx;
|
|
position: relative;
|
|
width: 52rpx;
|
|
height: 88rpx;
|
|
background-size: cover;
|
|
background-repeat: no-repeat;
|
|
background-image: url("https://image.fulllinkai.com/202308/15/f5461afc6ade909fa61a6be0b8e2a084.png");
|
|
overflow: hidden;
|
|
}
|
|
.ui-icon-change:before{
|
|
content: '';
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 52rpx;
|
|
height: 88rpx;
|
|
background: #757575;
|
|
animation: volumeChange 2.5s linear infinite;
|
|
}
|
|
@keyframes volumeChange {
|
|
0%{
|
|
bottom: 0rpx;
|
|
}
|
|
16%{
|
|
bottom: 14rpx;
|
|
}
|
|
32%{
|
|
bottom: 28rpx;
|
|
}
|
|
48%{
|
|
bottom: 42rpx;
|
|
}
|
|
64%{
|
|
bottom: 56rpx;
|
|
}
|
|
78%{
|
|
bottom: 70rpx;
|
|
}
|
|
94%{
|
|
bottom: 88rpx;
|
|
}
|
|
100%{
|
|
bottom: 88rpx;
|
|
}
|
|
}
|
|
}
|
|
.ui-icon-text{
|
|
margin: 52rpx auto;
|
|
}
|
|
}
|
|
|
|
.m_inp_ct {
|
|
border: 0;
|
|
width: 100%;
|
|
height: 0rpx;
|
|
transition: height .2s;
|
|
-moz-transition: height .2s; /* Firefox 4 */
|
|
-webkit-transition: height .2s; /* Safari 和 Chrome */
|
|
-o-transition: height .2s; /* Opera */
|
|
transition-timing-function: linear;
|
|
overflow: hidden;
|
|
padding-top: 0rpx;
|
|
|
|
.u_xi {
|
|
width: 100%;
|
|
height: 2rpx;
|
|
background-color: #f5f5f7;
|
|
}
|
|
|
|
.u_imp_lst {
|
|
padding: 30rpx;
|
|
|
|
.m_impLst_img {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 20rpx;
|
|
background-color: white;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.m_inp_ct.sel {
|
|
height: 200rpx;
|
|
padding-top: 30rpx;
|
|
}
|
|
|
|
.m_inp_ct.emojiSel {
|
|
height: 400rpx;
|
|
padding-top: 30rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.m_prog {
|
|
background-color: #a8a8a8;
|
|
border-radius: 30rpx;
|
|
width: 200rpx;
|
|
|
|
.conic-progress {
|
|
margin: 50rpx auto;
|
|
position: relative;
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.conic-progress::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: 86%;
|
|
height: 86%;
|
|
border-radius: 50%;
|
|
background-color: #a8a8a8;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
.ui-report-box{
|
|
border-radius: 30rpx 30rpx 0 0;
|
|
.ui-report-item, .ui-report-item-v2{
|
|
height: 102rpx;
|
|
border-top: 2rpx solid #f5f5f5;
|
|
}
|
|
.ui-report-item-v2{
|
|
border-top: 8rpx solid #f5f5f5;
|
|
}
|
|
}
|
|
</style>
|
|
<template>
|
|
<view class="ui-chitchat">
|
|
<image class="m_tips_icon" src="https://image.fulllinkai.com/202305/05/2172ea48286be34e3a4e80a8c2a4571a.png" mode="aspectFit" @tap="reportShow = true"></image>
|
|
<scroll-view class="ui-scroll-view" style="height: {{windowHeight - bottomBoxH}}rpx;" :scroll-y="scrollY" upper-threshold="50" bindscrolltoupper="getHistoryMsg" scroll-into-view="{{toView}}" enable-flex="{{true}}">
|
|
<view class="ui-top-placeholder"></view>
|
|
<block v-show="loading">
|
|
<image v-if="chatInfoData.other_real_approved != 1" class="ui-tips-pic" src="https://image.fulllinkai.com/202203/22/2a0d6bba0289f28b8d816e4deb1efa4c.png" mode="widthFix"></image>
|
|
<view class="ui-tips-box">
|
|
<view class="font_28 color333 bold">
|
|
<image src="https://images.ufutx.com/202012/24/dcf6c6454e7bb280c07346dcdceef767.png" mode="widthFix" class="ui-tips_icon"></image>
|
|
聊天小贴士
|
|
</view>
|
|
<view class="font_24 ui-tips_text">
|
|
请各位会员自觉遵守法律法规,<span class="color-theme">遇到转款切勿相信,谨防上当受骗,</span>未实名认证的会员保持警惕;交友期保持必要的界限,保证自身安全,请勿轻易委身于人,<span class="color-theme">请勿和用户发生借贷关系,</span>否则后果自己承担。
|
|
</view>
|
|
</view>
|
|
</block>
|
|
<view class="ui-msg-data-box" v-show="msgList.length > 0">
|
|
<!-- <view class="text-center font_2 ui-pb-24 color666" v-if="finished">没有更多消息了</view>-->
|
|
<view v-for="(item, index) in msgList" :key="index" class="ui-msg-data" id="{{item.id}}">
|
|
<view class="text-center color999 font_24 ui-pb-16" v-if="item.showTime">{{item.time}}</view>
|
|
<view class="ui-relative {{!item.isSelf ? 'ui-left-msg-box f-fl' : 'ui-right-msg-box f-fr'}}">
|
|
<image v-if="item.isSelf && item.isSend == 2" class="ui-error-icon" src="https://image.fulllinkai.com/202408/16/26bce9092cd2c703f7d5b2d56ef9d132.png" mode="widthFix"></image>
|
|
<image v-if="!item.isSelf && item.isSend == 2" class="ui-error-icon-v2" src="https://image.fulllinkai.com/202408/16/26bce9092cd2c703f7d5b2d56ef9d132.png" mode="widthFix"></image>
|
|
<image v-if="!item.isSelf" class="ui-user-pic" :src="item.avatar" mode="aspectFill"></image>
|
|
<view class="{{item.isSelf ? 'ui-pr-12' : 'ui-pl-12'}}">
|
|
<view class="ui-relative">
|
|
<!--文本加表情信息-->
|
|
<view class="{{!item.isSelf ? 'ui-left-msg-radius ui-msg-left color3' : 'ui-right-msg-radius ui-msg-right white'}} font_28" v-if="item.msgType == 'text' || item.msgType == 'TEXT'">
|
|
<rich-text nodes="{{item.text}}"></rich-text>
|
|
</view>
|
|
<!--图片信息-->
|
|
<image v-if="item.msgType == 'image' || item.msgType == 'PICTURE'" class="ui-msg-left-pic" :style="{maxWidth: item.attach.w + 'rpx', maxHeight: item.attach.h + 'rpx'}" :src="item.attach.url" mode="aspectFill" @tap.stop="previewImage(item.attach.url)"></image>
|
|
<!--音频信息-->
|
|
<view v-if="item.msgType == 'audio' || item.msgType == 'AUDIO'" class="{{!item.isSelf ? 'ui-left-msg-radius ui-left-audio' : 'ui-right-msg-radius ui-right-audio white' }} ui-audio-box font_36 f-fc" :style="{width: item.audioDur < 20 ? '120rpx' :item.audioDur < 40 ? '180rpx' : '320rpx', maxWidth: '320rpx!important', minWidth: '120rpx!important'}" @tap.stop="playAudio(item.attach, index)">
|
|
<image v-if="!item.isSelf" class="{{!audioState || playAudioIndex != index ? 'ui-audio-icon' : 'ui-audio-icon-l-play'}}" src="https://image.fulllinkai.com/202308/09/a0e320ef4f498309745d35f6798e970f.png" mode="aspectFit" lazy-load="false"></image>
|
|
<image v-else class="{{!audioState || playAudioIndex != index ? 'ui-audio-icon' : 'ui-audio-icon-r-play'}}" src="https://image.fulllinkai.com/202308/09/5514071f2d388102b5672e46ea1922f4.png" mode="aspectFit" lazy-load="false"></image>
|
|
<view v-if="!audioState || playAudioIndex != index">{{item.audioDur+ '"'}}</view>
|
|
<view v-else>{{audioTime + '"'}}</view>
|
|
</view>
|
|
<!--视频信息-->
|
|
<view v-if="item.msgType == 'video' || item.msgType == 'VIDEO'" :style="{width: item.attach.w + 'rpx', height: item.attach.h + 'rpx', display: videoIndex == index ? 'none' : 'block'}" class="liveImg" mode="widthFix" @tap.stop="playVideo(index, item.id)">
|
|
<image v-if="videoIndex != index" class="ui-video-box" :src="item.attach.poster" :style="{width: item.attach.w + 'rpx', height: item.attach.h + 'rpx'}">
|
|
<view class="ui-vide-poster">
|
|
<image class="ui-video_play_icon" src="https://image.fulllinkai.com/202308/17/42c88bf039bb56f85cfcb9af0392ffb6.png"></image>
|
|
<view class="ui-video_play-text font_20 white">{{item.videoDur}}</view>
|
|
</view>
|
|
</image>
|
|
<video :id="item.id" :src="item.attach.url" v-if="videoIndex == index" play-btn-position="center" show-fullscreen-btn="{{false}}" controls custom-cache="{{true}}" direction="0" object-fit="{{videoIndex == index ? 'contain' : 'cover'}}" referrer-policy="origin" bindfullscreenchange="leaveVideo" class="videoCenter ui-video-r-box" :style="{width: item.attach.w + 'rpx', height: item.attach.h + 'rpx'}" :key="item.id">
|
|
</video>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<image v-if="item.isSelf" class="ui-user-pic" :src="item.avatar" mode="aspectFill"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="ui-bottom-input-box">
|
|
<!--输入文本加表情预览信息-->
|
|
<view class="replyView f-fcc animation-slide-bottom" v-if="msg.length > 17 && showReplyView" style="bottom: {{inputBoxH}}px;">
|
|
<view class="replyContent main-content-box" bindlongpress="copy" data-text="{{msg}}">
|
|
<rich-text nodes="{{replyContent}}"></rich-text>
|
|
</view>
|
|
</view>
|
|
<view class="f-fbc">
|
|
<view class="ui-microphone-box">
|
|
<image class="ui-microphone-image" @tap.stop="changeMicrophone" src="https://image.fulllinkai.com/202308/05/a6adc00602e0b26aa642c2551c84bf03.png" mode="aspectFit" lazy-load="false"></image>
|
|
</view>
|
|
<block v-if="!microphoneShow">
|
|
<view class="ui-input-box f-fcl">
|
|
<image class="ui-emoji-icon" src="https://images.ufutx.com/202108/03/2f4661c8d19e56faa068ffac52ac9762.png" mode="widthFix" @tap="changeSelectEmoji"></image>
|
|
<input class="ui-input font_28 color3 text-left" confirm-hold="{{true}}" v-model="msg" type="text" maxlength="-1" placeholder="真诚一些,收获好感..." confirm-type="send" cursorSpacing="26" bindinput="changeMsg" bindenter="changeMsg" bindfocus="InputFocus" @confirm="send">
|
|
</view>
|
|
<view class="ui-send-box f-fcr">
|
|
<image class="font_32 ui-send-icon f-fcc {{msg ? 'active' : ''}}" @tap="send" src="https://image.fulllinkai.com/202305/05/4a47a0db6e60853dedfcfdf08a5ca249.png" mode="aspectFit" lazy-load="false"></image>
|
|
<image class="ui_add_icon {{msg ? 'active' : ''}}" @tap="changeSelectPic" src="https://images.ufutx.com/202107/20/055e2a820dd94b6eb9fcb09db3622ec7.png" mode="aspectFit" lazy-load="false"></image>
|
|
</view>
|
|
</block>
|
|
<block v-else>
|
|
<view class="{{microphoneType ? 'ui-microphone-close' : 'ui-microphone-open color-333 font_32'}}" @longpress="handleRecordStart" @touchmove="handleTouchMove" @touchend.stop="handleRecordStop">{{ mircrophoneType ? '松开结束' :'按住说话' }}</view>
|
|
</block>
|
|
</view>
|
|
<view class="m_inp_ct {{emojiShow ? 'emojiSel' : ''}}">
|
|
<block v-if="emojiShow">
|
|
<chatEmoji :emojiArray="emojiList.emoji" @selectEmoji="selectEmoji"></chatEmoji>
|
|
</block>
|
|
</view>
|
|
<view class="m_inp_ct {{openShow ? 'sel' : ''}}">
|
|
<view class="u_xi"></view>
|
|
<view class="f-fc">
|
|
<view class="u_imp_lst" v-for="(item,index) in operationList" :key="index" @tap="changeOperation(item.title)">
|
|
<view class="m_impLst_img f-fcc">
|
|
<image src="{{item.icon}}" mode="aspectFit" lazy-load="false"></image>
|
|
</view>
|
|
<view class="color-333 text-center font_22">{{ item.title }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!--长按录音-->
|
|
<view v-if="microphoneType" class="ui-microphone-message">
|
|
<view class="{{sendLock ? 'ui-icon-change-stop' : ''}} ui-icon-box">
|
|
<image class="ui-icon-microphone" @tap="changeMicrophone" src="https://image.fulllinkai.com/202308/05/97e1aa711ec3bf688f0853ea8d3444f0.png" mode="aspectFit" lazy-load="false"></image>
|
|
<view class="ui-icon-change"></view>
|
|
</view>
|
|
<view class="ui-icon-text white font_24">{{sendLock ? '松开手指,取消发送' : '手指上滑,取消发送'}}</view>
|
|
</view>
|
|
<!--上传进度展示-->
|
|
<view class="cu-modal {{uploadState ? 'show' : ''}}" style="background: rgba(0,0,0,0);">
|
|
<view class="cu-dialog m_prog">
|
|
<view class="conic-progress" style="background-image: conic-gradient(#fff {{progressValue}}%,#a8a8a8 0%);">
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="cu-modal bottom-modal" :class="{'show' : reportShow}" @tap="reportShow = false">
|
|
<view class="cu-dialog dialog ui-pb-40 ui-report-box">
|
|
<view class="f-fcc font_28 color333 ui-report-item" @tap="deleteFriends">删除好友</view>
|
|
<view class="f-fcc font_28 color333 ui-report-item" @tap="shield">拉黑并屏蔽</view>
|
|
<view class="f-fcc font_28 color333 ui-report-item" @tap="report">举报用户</view>
|
|
<view class="f-fcc font_28 color999 ui-report-item-v2" @tap="reportShow = false">取消</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import wepy from '@wepy/core'
|
|
import https from '../../mixins/https'
|
|
import base from '../../mixins/base'
|
|
import {service} from '../../config'
|
|
import {getTime, format, timeContrast, getVideoTime} from '../../mixins/plugins'
|
|
import emojiObj from '../../components/chatEmojiFile/emoji'
|
|
|
|
const app = getApp().$wepy.$options
|
|
|
|
wepy.page({
|
|
config: {},
|
|
mixins: [https, base],
|
|
|
|
data: {
|
|
loading: false,
|
|
myAvatar: '',
|
|
myUserId: '',
|
|
myName: '',
|
|
myType: '',
|
|
|
|
otherAvatar: '',
|
|
otherUserId: '',
|
|
otherUserType: '',
|
|
otherUserName: '',
|
|
|
|
chatInfoData: {},
|
|
reportShow: false, // 举报
|
|
throttle: true,
|
|
|
|
recorderManager: wx.getRecorderManager(),
|
|
startPoint: 0,
|
|
scrollY: true,
|
|
sendLock: true, // audio发送锁
|
|
microphoneShow: false,
|
|
microphoneType: false, // 按住或松开
|
|
openShow: false,
|
|
emojiList: [],
|
|
emojiShow: false,
|
|
emojiType: 'session',
|
|
|
|
operationList: [
|
|
{
|
|
icon: 'https://image.fulllinkai.com/202308/09/ef0d4e64d4f6fdfbe0f0ef21723e4d7b.png',
|
|
title: '图片'
|
|
},
|
|
{
|
|
icon: 'https://image.fulllinkai.com/202308/09/05550f0306f9b6057ea42ed3e4246a0e.png',
|
|
title: '相机'
|
|
},
|
|
{
|
|
icon: 'https://image.fulllinkai.com/202308/09/5154e58fe8f46a7a26a8bf6c507c6def.png',
|
|
title: '视频'
|
|
}
|
|
],
|
|
|
|
videoIndex: -1,
|
|
videoContext: null,
|
|
videoState: null,
|
|
|
|
playAudioIndex: -1,
|
|
audioTime: null,
|
|
audioState: null,
|
|
|
|
toView: '',
|
|
uploadState: false,
|
|
progressValue: 0, // 上传进度
|
|
lastId: '', // 历史记录分页数据最后一条id
|
|
lastTime: '', // 历史记录分页数据最后一条的时间戳
|
|
lastMsgId: '', // 历史记录分页数据最后一条的id
|
|
beginTime: '', // 历史记录分页数据最后一条的时间
|
|
finished: false, // 数据已全部获取完成
|
|
msgList: [],
|
|
showReplyView: true,
|
|
inputBoxH: 86,
|
|
bottomBoxH: 0,
|
|
windowHeight: 0,
|
|
replyContent: '',
|
|
msg: ''
|
|
},
|
|
methods: {
|
|
// 获取对方是否认证,并且标记消息已读
|
|
getChatInfo() {
|
|
let vm = this
|
|
let data = {user_id: `${vm.otherUserId}`}
|
|
vm.$get({url: `${service.host}/app/chat/info`, data}).then(({code, data}) => {
|
|
if (code === 0) {
|
|
vm.chatInfoData = data
|
|
}
|
|
}).catch(err => {
|
|
wx.hideLoading()
|
|
console.log(err)
|
|
})
|
|
},
|
|
|
|
// 发送文本和表情包消息
|
|
send() {
|
|
let vm = this
|
|
let timeData = new Date().getTime()
|
|
if (!vm.msg) {
|
|
vm.$showToast('请输入聊天内容')
|
|
return
|
|
}
|
|
if (/\[[^\]]+\]/.test(vm.msg)) {
|
|
vm.msg = vm.transitionMsg(vm.msg)
|
|
}
|
|
vm.msgList.push({
|
|
text: vm.msg,
|
|
attach: '',
|
|
id: `id_${timeData}`,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
name: vm.myName,
|
|
userId: vm.myUserId,
|
|
isSend: 0,
|
|
msgType: 'text'
|
|
})
|
|
vm.toView = `id_${timeData}`
|
|
let msgIndex = 0
|
|
let msgNewObj = {}
|
|
msgIndex = vm.msgList.findIndex((e) => e.timestamp == timeData)
|
|
app.globalData.nim.msg.sendTextMsg({
|
|
scene: 'p2p',
|
|
to: vm.otherUserId,
|
|
body: vm.msg,
|
|
isSend: 0,
|
|
onSendBefore: function (msg) {
|
|
console.log('get msg before', msg)
|
|
if (/\[[^\]]+\]/.test(vm.msg)) {
|
|
vm.msg = vm.transitionMsg(vm.msg)
|
|
}
|
|
msgNewObj = {
|
|
text: vm.msg,
|
|
attach: '',
|
|
id: `id_${msg.time}`,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
time: getTime(format(msg.time)),
|
|
showTime: timeContrast(format(msg.time), vm.lastTime),
|
|
name: vm.myName,
|
|
userId: msg.from,
|
|
isSend: 1,
|
|
msgType: 'text'
|
|
}
|
|
vm.msgList.splice(msgIndex, 1, msgNewObj)
|
|
vm.lastTime = format(msg.time)
|
|
vm.callbackSend('text')
|
|
}
|
|
})
|
|
},
|
|
// 发送图片消息
|
|
sendPictures(file) {
|
|
let vm = this
|
|
vm.openShow = false
|
|
vm.uploadState = true
|
|
vm.progressValue = 5
|
|
app.globalData.nim.msg.sendImageMsg({
|
|
scene: 'p2p',
|
|
to: vm.otherUserId,
|
|
type: 'image',
|
|
filePath: file,
|
|
onUploadProgress: function (progress) {
|
|
console.log(progress, '上传进度')
|
|
vm.progressValue = progress.percentage
|
|
},
|
|
onSendBefore: function (msg) {
|
|
console.log(msg, '上传完成, 图片信息')
|
|
vm.msgList.push({
|
|
text: '',
|
|
attach: vm.calculatePic(msg.attach, msg.type),
|
|
id: `id_${msg.time}`,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
time: getTime(format(msg.time)),
|
|
showTime: timeContrast(format(msg.time), vm.lastTime),
|
|
name: msg.fromNick,
|
|
userId: msg.from,
|
|
isSend: msg.status == 'sendFailed' ? 2 : 1, // sendFailed 发送失败
|
|
msgType: 'image'
|
|
})
|
|
vm.lastTime = format(msg.time)
|
|
vm.callbackSend('picture')
|
|
vm.$nextTick(() => {
|
|
vm.toView = `id_${msg.time}`
|
|
})
|
|
// 防止图片撑开触发加载历史数据
|
|
vm.$nextTick(() => {
|
|
setTimeout(() => {
|
|
vm.uploadState = false
|
|
}, 500)
|
|
})
|
|
}
|
|
})
|
|
},
|
|
// 发送视频
|
|
sendVideos(file) {
|
|
let vm = this
|
|
vm.openShow = false
|
|
vm.uploadState = true
|
|
vm.progressValue = 5
|
|
try {
|
|
app.globalData.nim.msg.sendVideoMsg({
|
|
scene: 'p2p',
|
|
to: vm.otherUserId,
|
|
type: 'video',
|
|
filePath: file,
|
|
onUploadProgress: function (progress) {
|
|
console.log(progress, '上传进度')
|
|
vm.progressValue = progress.percentage
|
|
},
|
|
onSendBefore: function (msg) {
|
|
console.log(msg, '上传完成,视频信息')
|
|
vm.msgList.push({
|
|
text: '',
|
|
attach: vm.calculatePic(msg.attach, msg.type),
|
|
id: `id_${msg.time}`,
|
|
timestamp: msg.time,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
time: getTime(format(msg.time)),
|
|
showTime: timeContrast(format(msg.time), vm.lastTime),
|
|
videoDur: getVideoTime(msg.attach.dur),
|
|
name: msg.fromNick,
|
|
userId: msg.from,
|
|
isSend: 1,
|
|
msgType: 'video'
|
|
})
|
|
vm.lastTime = format(msg.time)
|
|
vm.callbackSend('video')
|
|
vm.$nextTick(() => {
|
|
vm.toView = `id_${msg.time}`
|
|
})
|
|
// 防止视频撑开触发加载历史数据
|
|
vm.$nextTick(() => {
|
|
setTimeout(() => {
|
|
vm.uploadState = false
|
|
}, 500)
|
|
})
|
|
}
|
|
})
|
|
} catch (err) {
|
|
vm.sendFileError()
|
|
}
|
|
},
|
|
// 发送语音
|
|
sendAudio(file) {
|
|
let vm = this
|
|
vm.openShow = false
|
|
vm.uploadState = true
|
|
vm.progressValue = 5
|
|
app.globalData.nim.msg.sendAudioMsg({
|
|
scene: 'p2p',
|
|
to: vm.otherUserId,
|
|
type: 'audio',
|
|
filePath: file,
|
|
onUploadProgress: function (progress) {
|
|
console.log(progress, '上传进度')
|
|
vm.progressValue = progress.percentage
|
|
},
|
|
onSendBefore: function (msg) {
|
|
console.log(msg, '上传完成,音频信息')
|
|
vm.msgList.push({
|
|
text: '',
|
|
attach: msg.attach,
|
|
id: `id_${msg.time}`,
|
|
timestamp: msg.time,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
time: getTime(format(msg.time)),
|
|
showTime: timeContrast(format(msg.time), vm.lastTime),
|
|
videoDur: getVideoTime(msg.attach.dur),
|
|
audioDur: (msg.attach.dur / 1000).toFixed(0),
|
|
name: msg.fromNick,
|
|
userId: msg.from,
|
|
isSend: 1,
|
|
msgType: 'audio'
|
|
})
|
|
vm.lastTime = format(msg.time)
|
|
vm.callbackSend('audio')
|
|
vm.$nextTick(() => {
|
|
vm.toView = `id_${msg.time}`
|
|
// 防止音频撑开触发加载历史数据
|
|
setTimeout(() => {
|
|
vm.uploadState = false
|
|
}, 500)
|
|
})
|
|
}
|
|
})
|
|
},
|
|
// 发送图片或视频失败
|
|
sendFileError() {
|
|
let vm = this
|
|
let timeData = new Date().getTime()
|
|
vm.msgList.push({
|
|
text: '',
|
|
attach: {url: 'https://image.fulllinkai.com/202408/19/fc68d5ba0d7c952f08e2ae3f04ed70a9.png', w: 200, h: 162},
|
|
id: `id_${timeData}`,
|
|
isSelf: true,
|
|
avatar: vm.myAvatar,
|
|
name: vm.myName,
|
|
userId: vm.myUserId,
|
|
isSend: 2,
|
|
msgType: 'image'
|
|
})
|
|
vm.lastTime = format(timeData)
|
|
vm.$nextTick(() => {
|
|
vm.toView = `id_${timeData}`
|
|
// 防止音频撑开触发加载历史数据
|
|
setTimeout(() => {
|
|
vm.uploadState = false
|
|
}, 500)
|
|
})
|
|
},
|
|
// 发送信息后回调
|
|
callbackSend(type) {
|
|
let vm = this
|
|
let data = {
|
|
other_user_id: vm.otherUserId * 1,
|
|
field_7: vm.msg,
|
|
field_6: type
|
|
}
|
|
vm.$post({url: `${service.host}/chat/message/send`, data}).then(() => {
|
|
wx.hideLoading()
|
|
vm.msg = ''
|
|
vm.emojiShow = false
|
|
vm.replyContent = ''
|
|
}).catch(() => {
|
|
vm.uploadState = false
|
|
wx.hideLoading()
|
|
})
|
|
},
|
|
// 标记信息已读
|
|
sendMsgReceipt(e) {
|
|
app.globalData.nim.msg.sendMsgReceipt({
|
|
msg: e
|
|
})
|
|
},
|
|
// 在当前页面接收到别人发送过来的消息
|
|
reception(e) {
|
|
let vm = this
|
|
vm.sendMsgReceipt(e)
|
|
// vm.getChatInfo()
|
|
if (e.type == 'text' && /\[[^\]]+\]/.test(e.body)) {
|
|
e.body = vm.transitionMsg(e.body)
|
|
}
|
|
vm.msgList.push({
|
|
text: e.body,
|
|
attach: vm.calculatePic(e.attach, e.type),
|
|
id: `id_${e.time}`,
|
|
timestamp: e.time,
|
|
isSelf: false,
|
|
avatar: vm.otherAvatar,
|
|
time: getTime(format(e.time)),
|
|
showTime: timeContrast(format(e.time), vm.msgList && vm.msgList.length > 0 ? `${vm.msgList[vm.msgList.length - 1].timestamp}` : ''),
|
|
videoDur: e.type == 'video' ? getVideoTime(e.attach.dur) : '',
|
|
audioDur: e.type == 'audio' ? (e.attach.dur / 1000).toFixed(0) : '',
|
|
name: e.fromNick,
|
|
userId: e.from,
|
|
isSend: 1,
|
|
msgType: e.type
|
|
})
|
|
vm.toView = `id_${e.time}`
|
|
vm.lastTime = format(e.time)
|
|
},
|
|
// 获取历史消息数据
|
|
getHistoryMsg() {
|
|
let vm = this
|
|
let data = {
|
|
min_id: vm.lastId
|
|
}
|
|
if (vm.uploadState || vm.videoState) {
|
|
return
|
|
}
|
|
if (vm.finished) {
|
|
return
|
|
}
|
|
vm.$showLoading('')
|
|
vm.$get({url: `${service.host}/chat/user/${vm.otherUserId}/message/list`, data}).then(({code, data}) => {
|
|
if (code === 0) {
|
|
if (data && data.length > 0) {
|
|
data.forEach((item, index) => {
|
|
item.time = new Date(item.create_time.replace(/[-]/g, '/').replace(/[-]/, '')).getTime()
|
|
item.attach = item.attach ? JSON.parse(item.attach) : ''
|
|
item.showTime = timeContrast(format(item.time), vm.lastTime)
|
|
item.timing = getTime(format(item.time))
|
|
if (item.showTime && index > 0) {
|
|
data[index].showTime = false
|
|
data[index - 1].showTime = true
|
|
}
|
|
if ((item.content_type == 'text' || item.content_type == 'TEXT') && /\[[^\]]+\]/.test(item.content)) {
|
|
item.body = vm.transitionMsg(item.content)
|
|
} else {
|
|
item.body = item.content
|
|
}
|
|
vm.lastTime = format(item.time)
|
|
})
|
|
|
|
vm.lastMsgId = data[data.length - 1].id
|
|
vm.beginTime = data[data.length - 1].time
|
|
|
|
setTimeout(() => {
|
|
data.forEach((item) => {
|
|
vm.msgList.unshift({
|
|
text: item.body,
|
|
attach: vm.calculatePic(item.attach, item.content_type),
|
|
id: `id_${item.time}`,
|
|
timestamp: item.time,
|
|
isSelf: item.is_mine == 0 ? false : true,
|
|
avatar: item.is_mine == 0 ? vm.otherAvatar : vm.myAvatar,
|
|
time: item.timing,
|
|
showTime: item.showTime,
|
|
videoDur: item.content_type == 'video' || item.content_type == 'VIDEO' ? getVideoTime(item.attach.dur) : '',
|
|
audioDur: item.content_type == 'audio' || item.content_type == 'AUDIO' ? (item.attach.dur / 1000).toFixed(0) : '',
|
|
name: item.fromNick,
|
|
isSend: 1,
|
|
userId: item.from,
|
|
msgType: item.content_type
|
|
})
|
|
})
|
|
console.log(vm.msgList)
|
|
vm.$nextTick(() => {
|
|
vm.toView = `id_${data[0].time}`
|
|
if (vm.msgList.length > 15) {
|
|
vm.scrollY = false
|
|
}
|
|
vm.lastId = `${data[data.length - 1].id}`
|
|
vm.loading = true
|
|
// 防止撑开触发加载历史数据
|
|
setTimeout(() => {
|
|
vm.uploadState = false
|
|
vm.scrollY = true
|
|
}, 500)
|
|
})
|
|
})
|
|
} else {
|
|
vm.loading = true
|
|
vm.scrollY = true
|
|
}
|
|
if (data && data.length < 15) {
|
|
vm.finished = true
|
|
}
|
|
}
|
|
}).catch(err => {
|
|
wx.hideLoading()
|
|
console.log(err)
|
|
})
|
|
},
|
|
// 删除好友
|
|
deleteFriends() {
|
|
let vm = this
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '是否确认删除该好友',
|
|
success: function (res) {
|
|
if (res.confirm) {
|
|
vm.$showLoading('')
|
|
vm.$post({url: `${service.host}/friend/users/${vm.otherUserId}`}).then(({code, data}) => {
|
|
if (code == 0) {
|
|
vm.$showToast(`好友已删除`)
|
|
setTimeout(() => {
|
|
wx.switchTab({url: '/pages/tabBar/news'})
|
|
}, 1200)
|
|
}
|
|
wx.hideLoading()
|
|
}).catch(() => {
|
|
wx.hideLoading()
|
|
})
|
|
} else if (res.cancel) {
|
|
console.log('用户点击取消')
|
|
}
|
|
}
|
|
})
|
|
},
|
|
// 加入黑名单并屏蔽
|
|
shield() {
|
|
let vm = this
|
|
wx.showModal({
|
|
title: '加入黑名单',
|
|
content: '拉黑后,对方将无法访问、关注、发送好友请求,也无法给你发消息,可以在【设置-黑名单】中取消',
|
|
success: function (res) {
|
|
if (res.confirm) {
|
|
vm.$showLoading('')
|
|
vm.$post({url: `${service.host}/blacklist/friends/${vm.otherUserId}`}).then(({code, data}) => {
|
|
if (code == 0) {
|
|
vm.$showToast(`已加入黑名单`)
|
|
setTimeout(() => {
|
|
wx.switchTab({url: '/pages/tabBar/news'})
|
|
}, 1200)
|
|
}
|
|
wx.hideLoading()
|
|
}).catch(() => {
|
|
wx.hideLoading()
|
|
})
|
|
} else if (res.cancel) {
|
|
console.log('用户点击取消')
|
|
}
|
|
}
|
|
})
|
|
},
|
|
// 举报
|
|
report() {
|
|
let vm = this
|
|
vm.reportShow = false
|
|
wx.navigateTo({url: `/pages/users/report?id=${vm.otherUserId}&type=details`})
|
|
},
|
|
// 监听底部输入框的高度
|
|
changeInputHeight(e) {
|
|
let vm = this
|
|
let query = wx.createSelectorQuery()
|
|
query.select('.ui-bottom-input-box').boundingClientRect((res) => {
|
|
if (res) {
|
|
vm.inputBoxH = res.height
|
|
}
|
|
if (e) {
|
|
vm.bottomBoxH = res.height * 2
|
|
}
|
|
}).exec()
|
|
},
|
|
// 监听输入框内容
|
|
changeMsg(e) {
|
|
console.log(e, '8888')
|
|
let vm = this
|
|
if (/\[[^\]]+\]/.test(e.$wx.detail.value)) {
|
|
vm.replyContent = vm.transitionMsg(e.$wx.detail.value)
|
|
} else {
|
|
vm.replyContent = e.$wx.detail.value
|
|
}
|
|
vm.changeInputHeight()
|
|
},
|
|
// 输入框聚焦事件
|
|
InputFocus() {
|
|
let vm = this
|
|
vm.emojiShow = false
|
|
vm.openShow = false
|
|
vm.showReplyView = false
|
|
setTimeout(() => {
|
|
vm.changeInputHeight()
|
|
vm.showReplyView = true
|
|
}, 500)
|
|
},
|
|
// 录音授权
|
|
changeMicrophone() {
|
|
let vm = this
|
|
wx.authorize({
|
|
scope: 'scope.record',
|
|
success() {
|
|
console.log('录音授权成功')
|
|
// 第一次成功授权后
|
|
vm.microphoneShow = !vm.microphoneShow
|
|
},
|
|
fail() {
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '您未授权录音,功能将无法使用',
|
|
showCancel: true,
|
|
confirmText: '授权',
|
|
confirmColor: '#52a2d8',
|
|
success: function (res) {
|
|
if (res.confirm) {
|
|
wx.openSetting({
|
|
success: (res) => {
|
|
if (!res.authSetting['scope.record']) {
|
|
// 未设置录音授权
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '您未授权录音,功能将无法使用',
|
|
showCancel: false,
|
|
success: function (res) {
|
|
}
|
|
})
|
|
} else {
|
|
// 第二次成功授权
|
|
vm.microphoneShow = !vm.microphoneShow
|
|
}
|
|
},
|
|
fail: function () {
|
|
console.log('授权设置录音失败')
|
|
}
|
|
})
|
|
} else if (res.cancel) {
|
|
console.log('cancel')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
},
|
|
handleRecordStart(e) { // 长按语音
|
|
let vm = this
|
|
const options = {
|
|
sampleRate: 16000, // 采样率
|
|
numberOfChannels: 1, // 录音通道数
|
|
encodeBitRate: 96000, // 编码码率
|
|
format: 'mp3', // 音频格式,有效值 aac/mp3
|
|
frameSize: 50// 指定帧大小,单位 KB
|
|
}
|
|
vm.recorderManager.start(options)
|
|
vm.startPoint = e.touches[0]// 记录长按时开始点信息,后面用于计算上划取消时手指滑动的距离。
|
|
vm.microphoneType = true
|
|
vm.sendLock = false // 长按时是不上锁的。
|
|
vm.recorderManager.onStart(() => {
|
|
console.log('recorder start')
|
|
})
|
|
vm.recorderManager.onError((err) => {
|
|
console.log(err, 'err--')
|
|
})
|
|
},
|
|
handleTouchMove(e) { // 上滑取消
|
|
let vm = this
|
|
let moveLenght = e.touches[e.touches.length - 1].clientY - vm.startPoint.clientY // 移动距离
|
|
vm.sendLock = Math.abs(moveLenght) > 50
|
|
},
|
|
// 松开发送语音
|
|
handleRecordStop() {
|
|
let vm = this
|
|
vm.microphoneType = false
|
|
vm.recorderManager.stop()
|
|
vm.recorderManager.onStop((res) => {
|
|
console.log(res, 'res----')
|
|
console.log(res.tempFilePath, 'res----')
|
|
if (!vm.sendLock) {
|
|
vm.sendAudio(res.tempFilePath)
|
|
}
|
|
})
|
|
vm.recorderManager.onError((err) => {
|
|
console.log(err, 'err--')
|
|
})
|
|
},
|
|
// 展示/关闭弹出表情包
|
|
changeSelectEmoji() {
|
|
let vm = this
|
|
vm.showReplyView = false
|
|
vm.openShow = false
|
|
vm.emojiShow = !vm.emojiShow
|
|
setTimeout(() => {
|
|
vm.changeInputHeight()
|
|
vm.showReplyView = true
|
|
}, 500)
|
|
},
|
|
// 展示/关闭弹出选择图片
|
|
changeSelectPic() {
|
|
let vm = this
|
|
vm.emojiShow = false
|
|
vm.openShow = !vm.openShow
|
|
setTimeout(() => {
|
|
vm.changeInputHeight()
|
|
}, 500)
|
|
},
|
|
// 选择表情包
|
|
selectEmoji(e) {
|
|
let vm = this
|
|
vm.msg = vm.msg + e
|
|
if (/\[[^\]]+\]/.test(vm.msg)) {
|
|
vm.replyContent = vm.transitionMsg(vm.msg)
|
|
}
|
|
vm.changeInputHeight()
|
|
},
|
|
// 转换msg表情数据
|
|
transitionMsg(e) {
|
|
let vm = this
|
|
let emojiItems = e.match(/\[[^\]]+\]/g)
|
|
emojiItems.forEach(text => {
|
|
let emojiCnt = vm.emojiList.emoji.list
|
|
emojiCnt.forEach(emItem => {
|
|
if (emItem.key == text) {
|
|
e = e.replace(text, `<img class="emoji_small" src="${emItem.img}" />`)
|
|
}
|
|
})
|
|
})
|
|
e = '<div class="emoji_text">' + e + '</div>'
|
|
return e
|
|
},
|
|
// 获取emoji表情包数据
|
|
emojiCts() {
|
|
return this.genEmojiList('emoji', emojiObj.emojiList)
|
|
},
|
|
// 获取表情包
|
|
genEmojiList(type, emojiList) {
|
|
let result = {}
|
|
for (let name in emojiList) {
|
|
let emojiMap = emojiList[name]
|
|
let list = []
|
|
for (let key in emojiMap) {
|
|
list.push({
|
|
type,
|
|
name,
|
|
key,
|
|
img: emojiMap[key].img
|
|
})
|
|
}
|
|
if (list.length > 0) {
|
|
result[name] = {
|
|
type,
|
|
name,
|
|
list,
|
|
album: list[0].img
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
},
|
|
// 图片大小计算
|
|
calculatePic(e, type) {
|
|
if (!e) {
|
|
return ''
|
|
}
|
|
let wRatio = 0
|
|
if ((type == 'video' || type == 'VIDEO') && e.url && e.url.includes('?')) {
|
|
e.poster = `${e.url}&vframe`
|
|
} else if ((type == 'video' || type == 'VIDEO') && e.url) {
|
|
e.poster = `${e.url}?vframe`
|
|
}
|
|
if (e.w > e.h) {
|
|
wRatio = e.w / 200
|
|
e.w = 200
|
|
e.h = e.h / wRatio
|
|
} else {
|
|
wRatio = e.h / 200
|
|
e.w = e.w / wRatio
|
|
e.h = 200
|
|
}
|
|
console.log(e, '8988888')
|
|
return e
|
|
},
|
|
// 更多操作
|
|
changeOperation(title) {
|
|
let vm = this
|
|
if (title == '图片') {
|
|
vm.onAlbum(['album'])
|
|
} else if (title == '相机') {
|
|
vm.onAlbum(['camera'])
|
|
} else {
|
|
vm.chooseVideo()
|
|
}
|
|
},
|
|
// 选择图片发送
|
|
onAlbum(sourceType) {
|
|
let vm = this
|
|
wx.chooseMedia({
|
|
count: 1,
|
|
mediaType: ['image'],
|
|
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
|
sourceType, // 可以指定来源是相册还是相机,默认二者都有
|
|
success: (res) => {
|
|
console.log('res--------------------------', res)
|
|
let imgSrc = res.tempFiles[0].tempFilePath
|
|
vm.sendPictures(imgSrc)
|
|
}
|
|
})
|
|
},
|
|
// 选择视频
|
|
chooseVideo() {
|
|
let vm = this
|
|
wx.chooseMedia({
|
|
count: 1,
|
|
mediaType: ['video'],
|
|
sizeType: ['compressed'],
|
|
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
|
success: (res) => {
|
|
console.log('res--------------------------', res)
|
|
let imgSrc = res.tempFiles[0].tempFilePath
|
|
vm.sendVideos(imgSrc)
|
|
}
|
|
})
|
|
},
|
|
// 播放视频
|
|
playVideo(index, e) {
|
|
let vm = this
|
|
vm.videoState = true
|
|
vm.videoIndex = index
|
|
vm.videoContext = wx.createVideoContext(`${e}`)
|
|
vm.videoContext.requestFullScreen()
|
|
setTimeout(function() {
|
|
// 将点击视频进行播放
|
|
vm.videoContext = wx.createVideoContext(`${e}`)
|
|
vm.videoContext.play()
|
|
}, 1200)
|
|
},
|
|
// 关闭视频
|
|
leaveVideo(e, row) {
|
|
let vm = this
|
|
let fullScreen = e.$wx.detail.fullScreen
|
|
vm.videoState = true
|
|
if (!fullScreen) {
|
|
vm.toView = `${row}`
|
|
vm.videoContext.stop()
|
|
vm.videoContext = null
|
|
vm.videoIndex = -1
|
|
setTimeout(() => {
|
|
vm.videoState = false
|
|
}, 500)
|
|
}
|
|
},
|
|
// 播放音频
|
|
playAudio(row, index) {
|
|
let vm = this
|
|
vm.audioState = !vm.audioState
|
|
vm.playAudioIndex = index
|
|
const innerAudioContext = wx.createInnerAudioContext({
|
|
useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
|
|
})
|
|
let myTime = null
|
|
if (vm.audioState) {
|
|
innerAudioContext.src = row.url
|
|
innerAudioContext.play() // 播放
|
|
vm.audioTime = 0
|
|
myTime = setInterval(() => {
|
|
vm.audioTime += 1
|
|
if (vm.audioTime * 1000 > row.dur) {
|
|
clearInterval(myTime)
|
|
vm.audioState = false
|
|
vm.playAudioIndex = -1
|
|
}
|
|
}, 1000)
|
|
} else {
|
|
clearInterval(myTime)
|
|
vm.audioState = false
|
|
vm.playAudioIndex = -1
|
|
}
|
|
},
|
|
// 预览图片
|
|
previewImage(imge) {
|
|
let vm = this
|
|
let imageArr = []
|
|
vm.msgList.forEach((item) => {
|
|
if (item.msgType == 'image') {
|
|
imageArr.push(item.attach.url)
|
|
}
|
|
})
|
|
// 倒序处理阅览顺序不对的问题
|
|
imageArr = imageArr.reverse()
|
|
vm.$previewImages(imge, imageArr)
|
|
}
|
|
},
|
|
|
|
onShow() {
|
|
let vm = this
|
|
vm.myUserId = wx.getStorageSync('user_id')
|
|
vm.myType = wx.getStorageSync('userInfo').type
|
|
vm.myName = wx.getStorageSync('userInfo').name
|
|
vm.myAvatar = wx.getStorageSync('userInfo').avatar
|
|
// vm.getChatInfo()
|
|
},
|
|
onLoad(e) {
|
|
let vm = this
|
|
vm.otherAvatar = e.pic
|
|
vm.otherUserId = e.id
|
|
vm.otherUserType = e.type
|
|
vm.otherUserName = decodeURIComponent(e.name)
|
|
// 获取表情包数据
|
|
vm.emojiList = vm.emojiCts()
|
|
// 获取手机屏幕高度
|
|
wx.getSystemInfo({
|
|
success: (res) => {
|
|
vm.windowHeight = res.windowHeight * 2
|
|
}
|
|
})
|
|
// 底部输入框高度
|
|
vm.changeInputHeight(true)
|
|
// vm.$nextTick(() => {
|
|
// setTimeout(() => {
|
|
// // 获取历史消息
|
|
// vm.getHistoryMsg()
|
|
// // 实时获取对方发送的消息
|
|
// app.globalData.nim.on('msg', function (e) {
|
|
// vm.reception(e)
|
|
// })
|
|
// }, 3000)
|
|
// })
|
|
vm.$nextTick(() => {
|
|
// 获取历史消息
|
|
vm.getHistoryMsg()
|
|
// 实时获取对方发送的消息
|
|
app.globalData.nim.on('msg', function (e) {
|
|
vm.reception(e)
|
|
})
|
|
})
|
|
wx.setNavigationBarTitle({
|
|
title: vm.otherUserName,
|
|
success: function () {}
|
|
})
|
|
},
|
|
created() {
|
|
}
|
|
})
|
|
</script>
|
|
<config>
|
|
{
|
|
navigationBarTitleText: '聊天',
|
|
enablePullDownRefresh: false,
|
|
backgroundColorTop: '#f2f2f2',
|
|
backgroundColorBottom: '#f2f2f2',
|
|
usingComponents: {
|
|
chatEmoji: '~@/components/chatEmojiFile/ChatEmoji'
|
|
}
|
|
}
|
|
</config>
|