Files
peiwan-uniapp/pages/im/components/chatBar.vue
2025-01-21 01:46:34 +08:00

1453 lines
36 KiB
Vue
Raw Permalink 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="input-box" :style="{bottom: keyboardHeight+'px'}" :class="popupLayerClass" @touchmove.stop.prevent="discard">
<view class="send-box">
<!-- <view>
<u-icon name="outline-voice-cricle" custom-prefix="iconfont" color="#333" :size="60" @tap="switchVoice" />
</view> -->
<view class="textbox">
<view class="text-mode">
<view class="box">
<textarea style="font-size: 12px;" placeholder="输入聊天内容" :adjust-position="false" :show-confirm-bar="false" auto-height="true" v-model="textMsg" @focus="textareaFocus"/>
</view>
</view>
</view>
<view class="icon" v-if="hideEmoji">
<u-icon name="vuesax-outline-happyemoji" custom-prefix="iconfont" color="#333" :size="60" @tap="chooseEmoji" />
</view>
<view class="icon" v-else>
<u-icon name="outline-keyboard" custom-prefix="iconfont" color="#333" :size="60" @tap="chooseEmoji" />
</view>
<view class="icon" :class="textMsg?'hidden':''">
<u-icon name="vuesax-outline-add-circle" custom-prefix="iconfont" color="#333" :size="60" @tap="showMore" />
</view>
<view class="send" :class="!textMsg?'hidden':''" @tap="sendText">
<view class="btn">{{btnText}}</view>
</view>
</view>
<view class="send-tool">
<view @tap="switchVoice">
<u-icon name="outline-microphone" custom-prefix="iconfont" color="#333" :size="60"/>
</view>
<view v-if="user.hasQrcode" @tap="getWeixin">
<u-icon name="weixin" custom-prefix="iconfont" color="#19be6b" :size="60" />
</view>
<view @tap="openGift">
<u-icon color="#f880ab" name="presentfill" :size="64" custom-prefix="iconfont"></u-icon>
</view>
<view @tap="chooseImage">
<u-icon name="outline-image" custom-prefix="iconfont" color="#333" :size="60" />
</view>
<view @tap="camera">
<u-icon name="outline-camera" custom-prefix="iconfont" color="#333" :size="60" />
</view>
<!-- <u-icon name="outline-map" custom-prefix="iconfont" color="#333" :size="60" />
<view @tap="openGift">
<u-icon name="outline-gift" custom-prefix="iconfont" color="#333" :size="60"/>
</view> -->
</view>
</view>
<!-- 抽屉栏 -->
<view class="popup-layer" :class="popupLayerClass" @touchmove.stop.prevent="discard">
<view class="emoji-view" :class="{hidden:hideEmoji}">
<!-- 表情 -->
<scroll-view scroll-y="true">
<view v-if="emojiScene == 'emoji'">
<view class="emoji-swiper" v-if="timeEmojiList.length > 0">
<view class="title">最近使用</view>
<view class="emoji-list">
<view class="emoji_tools1" v-for="(em,pid) in timeEmojiList" :key="pid" @tap="addEmoji(em, emojiScene)">
<text>{{em}}</text>
</view>
</view>
<view class="title">全部表情</view>
<view class="emoji-list">
<view class="emoji_tools1" v-for="(em,pid) in emojiList" :key="pid" @tap="addEmoji(em, emojiScene)">
<text>{{em}}</text>
</view>
</view>
<view class="del-btn" @tap="delBtn">
<u-icon name="backspace" color="#333" :size="40"/>
</view>
</view>
<view class="emoji-swiper" v-else>
<view class="emoji-list">
<view class="emoji_tools1" v-for="(em,pid) in emojiList" :key="pid" @tap="addEmoji(em, emojiScene)">
<text>{{em}}</text>
</view>
</view>
<view class="del-btn" @tap="delBtn">
<u-icon name="backspace" color="#333" :size="40"/>
</view>
</view>
</view>
<view v-if="emojiScene == 'like'">
<view class="emoji-swiper">
<view class="title">添加的单个表情</view>
<view class="emoji-list">
<view class="emoji_image">
<view class="emoji-add">
<u-icon name="plus" color="#333" :size="60"/>
</view>
</view>
<view class="emoji_image" v-for="(emoji,pid) in shopEmojiList" :key="pid" @tap="addEmoji(emoji, emojiScene)">
<image class="image" :src="emoji.src"></image>
</view>
</view>
</view>
</view>
<view v-if="emojiScene == 'shop'">
<view class="emoji-swiper">
<view class="title">一只小老虎</view>
<view class="emoji-list">
<view class="emoji_image" v-for="(emoji,pid) in shopEmojiList" :key="pid" @tap="addEmoji(emoji, emojiScene)">
<image class="image" :src="emoji.src"></image>
<text>{{emoji.name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
<!--选择表情类型栏-->
<scroll-view class="emoji-tools-scroll-view" scroll-x>
<view class="emoji-tool-box">
<view class="emoji-tools-item" :class="tindex == pid ? 'select' : ''" :data-i="pid" v-for="(tool,pid) in emojiTools" :key="pid" @tap="changeTool(pid)">
<u-icon v-if="tool.type == 'icon'" :name="tool.icon" custom-prefix="iconfont" :size="45"/>
<image class="img" mode="aspectFill" v-if="tool.type == 'image'" :src="tool.icon"/>
</view>
</view>
</scroll-view>
</view>
<!-- 更多功能 相册-拍照-红包 -->
<swiper class="tool-swiper" :class="{hidden:hideMore}" indicator-dots="true" duration="150">
<swiper-item class="tool-swiper-box">
<view class="tool-btn" v-if="user.hasQrcode" @tap="getWeixin">
<view class="btn-card">
<u-icon name="weixin" custom-prefix="iconfont" color="#19be6b" :size="55" />
</view>
<view class="btn-text">交换名片</view>
</view>
<view class="tool-btn" @tap="openGift">
<view class="btn-card">
<u-icon color="#f880ab" name="presentfill" :size="55" custom-prefix="iconfont"></u-icon>
</view>
<view class="btn-text">赠送礼物</view>
</view>
<view class="tool-btn" @tap="chooseImage">
<view class="btn-card">
<u-icon name="photo-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">发送照片</view>
</view>
<!--
<view class="tool-btn">
<view class="btn-card">
<u-icon name="creative-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">添加回复</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="time-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">聊天记录</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="image-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">发送照片</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="service-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">快捷回复</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="creative-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">添加回复</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="time-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">聊天记录</view>
</view> -->
</swiper-item>
<!-- <swiper-item class="tool-swiper-box">
<view class="tool-btn">
<view class="btn-card">
<u-icon name="location-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">发送位置</view>
</view>
<view class="tool-btn">
<view class="btn-card">
<u-icon name="warning-fill" color="#333" :size="55"/>
</view>
<view class="btn-text">举报拉黑</view>
</view>
</swiper-item> -->
</swiper>
<!-- 录音功能 -->
<view class="voice-center" :class="{hidden:isVoice}">
<all-speech ref="speech" @okClick="voiceOk"></all-speech>
</view>
</view>
</view>
</template>
<script>
import emoji from '@/pages/im/util/emoji';
//聊天栏 回复栏
export default {
components: {
},
props: {
//禁用聊天栏
isLocked: {
type: Boolean,
default: false
},
//是否显示遮罩
mask: {
type: Boolean,
default: true
},
//true表示遮罩透明
maskOpacity: {
type: Boolean,
default: true
},
keyboardHeight: {
type: Number,
default: -1
},
btnText: {
type: String,
default: '发送'
},
color: {
type: String,
default: '#5677fc'
},
user: {
type: Object,
default: {}
},
},
data() {
return {
// more参数
hideMore:true,
//表情定义
hideEmoji:true,
tindex: 0,
emojiScene: 'emoji',
timeEmojiList: ["😀", "😁", "😃", "😄"],
emojiList:[],
shopEmojiList: [
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水1',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水2',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如水',
},
{
src: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
name: '心静如',
},
],
//表情图片图床名称 ,由于我上传的第三方图床名称会有改变,所以有此数据来做对应,您实际应用中应该不需要
onlineEmoji:{"100.gif":"AbNQgA.gif","101.gif":"AbN3ut.gif","102.gif":"AbNM3d.gif","103.gif":"AbN8DP.gif","104.gif":"AbNljI.gif","105.gif":"AbNtUS.gif","106.gif":"AbNGHf.gif","107.gif":"AbNYE8.gif","108.gif":"AbNaCQ.gif","109.gif":"AbNN4g.gif","110.gif":"AbN0vn.gif","111.gif":"AbNd3j.gif","112.gif":"AbNsbV.gif","113.gif":"AbNwgs.gif","114.gif":"AbNrD0.gif","115.gif":"AbNDuq.gif","116.gif":"AbNg5F.gif","117.gif":"AbN6ET.gif","118.gif":"AbNcUU.gif","119.gif":"AbNRC4.gif","120.gif":"AbNhvR.gif","121.gif":"AbNf29.gif","122.gif":"AbNW8J.gif","123.gif":"AbNob6.gif","124.gif":"AbN5K1.gif","125.gif":"AbNHUO.gif","126.gif":"AbNIDx.gif","127.gif":"AbN7VK.gif","128.gif":"AbNb5D.gif","129.gif":"AbNX2d.gif","130.gif":"AbNLPe.gif","131.gif":"AbNjxA.gif","132.gif":"AbNO8H.gif","133.gif":"AbNxKI.gif","134.gif":"AbNzrt.gif","135.gif":"AbU9Vf.gif","136.gif":"AbUSqP.gif","137.gif":"AbUCa8.gif","138.gif":"AbUkGQ.gif","139.gif":"AbUFPg.gif","140.gif":"AbUPIS.gif","141.gif":"AbUZMn.gif","142.gif":"AbUExs.gif","143.gif":"AbUA2j.gif","144.gif":"AbUMIU.gif","145.gif":"AbUerq.gif","146.gif":"AbUKaT.gif","147.gif":"AbUmq0.gif","148.gif":"AbUuZV.gif","149.gif":"AbUliF.gif","150.gif":"AbU1G4.gif","151.gif":"AbU8z9.gif","152.gif":"AbU3RJ.gif","153.gif":"AbUYs1.gif","154.gif":"AbUJMR.gif","155.gif":"AbUadK.gif","156.gif":"AbUtqx.gif","157.gif":"AbUUZ6.gif","158.gif":"AbUBJe.gif","159.gif":"AbUdIO.gif","160.gif":"AbU0iD.gif","161.gif":"AbUrzd.gif","162.gif":"AbUDRH.gif","163.gif":"AbUyQA.gif","164.gif":"AbUWo8.gif","165.gif":"AbU6sI.gif","166.gif":"AbU2eP.gif","167.gif":"AbUcLt.gif","168.gif":"AbU4Jg.gif","169.gif":"AbURdf.gif","170.gif":"AbUhFS.gif","171.gif":"AbU5WQ.gif","172.gif":"AbULwV.gif","173.gif":"AbUIzj.gif","174.gif":"AbUTQs.gif","175.gif":"AbU7yn.gif","176.gif":"AbUqe0.gif","177.gif":"AbUHLq.gif","178.gif":"AbUOoT.gif","179.gif":"AbUvYF.gif","180.gif":"AbUjFU.gif","181.gif":"AbaSSJ.gif","182.gif":"AbUxW4.gif","183.gif":"AbaCO1.gif","184.gif":"Abapl9.gif","185.gif":"Aba9yR.gif","186.gif":"AbaFw6.gif","187.gif":"Abaiex.gif","188.gif":"AbakTK.gif","189.gif":"AbaZfe.png","190.gif":"AbaEFO.gif","191.gif":"AbaVYD.gif","192.gif":"AbamSH.gif","193.gif":"AbaKOI.gif","194.gif":"Abanld.gif","195.gif":"Abau6A.gif","196.gif":"AbaQmt.gif","197.gif":"Abal0P.gif","198.gif":"AbatpQ.gif","199.gif":"Aba1Tf.gif","200.png":"Aba8k8.png","201.png":"AbaGtS.png","202.png":"AbaJfg.png","203.png":"AbaNlj.png","204.png":"Abawmq.png","205.png":"AbaU6s.png","206.png":"AbaaXn.png","207.png":"Aba000.png","208.png":"AbarkT.png","209.png":"AbastU.png","210.png":"AbaB7V.png","211.png":"Abafn1.png","212.png":"Abacp4.png","213.png":"AbayhF.png","214.png":"Abag1J.png","215.png":"Aba2c9.png","216.png":"AbaRXR.png","217.png":"Aba476.png","218.png":"Abah0x.png","219.png":"Abdg58.png"},
emojiTools: [{
icon: 'emoji-good',
type: 'icon',
scene: 'emoji',
}/* ,{
icon: 'outline-heart',
type: 'icon',
scene: 'like',
},{
icon: 'https://rbtnet.oss-cn-hangzhou.aliyuncs.com/laohu.png',
type: 'image',
scene: 'shop',
} */],
//文字消息
textMsg:'',
// 抽屉参数
popupLayerClass:'',
//录音相关参数
timeOutEvent: 0,
// #ifndef H5
//H5不能录音
RECORDER:uni.getRecorderManager(),
// #endif
initPoint:{identifier:0,Y:0},
voiceTis:'按住 说话',
recordTis:"手指上滑 取消发送",
recordLength:0,
recordTimer:null,
isVoice:true,
willStop:false,
recording:false,
};
},
created() {
//键盘高度监听
let safeH = this.isPhoneX() ? 34 : 0;
/* uni.onKeyboardHeightChange(res => {
let h = res.height - safeH - 1;
this.keyboardHeight = h > 0 ? h : 0;
}); */
// #ifndef H5
//录音开始事件
this.RECORDER.onStart((e)=>{
this.recordBegin(e);
})
//录音结束事件
this.RECORDER.onStop((e)=>{
this.recordEnd(e);
})
// #endif
},
methods: {
//添加表情
addEmoji(em, scene){
if('emoji' == scene){
this.textMsg+=em;
}else{
this.$emit('sendEmoji', em);
}
},
openGift() {
this.hideDrawer();
this.$emit('openGift');
},
//获取焦点,则关闭抽屉
textareaFocus(){
this.hideDrawer();
},
changeTool(i) {
this.tindex = i;
this.emojiScene = this.emojiTools[i].scene;
if('shop' == this.emojiScene){
}
},
delBtn() {
var length = this.textMsg.length;
var str = this.textMsg.slice(length-2, length);
if(this.emojiList.includes(str)){
this.textMsg = this.textMsg.slice(0, length-2);
}else{
this.textMsg = this.textMsg.slice(0, length-1);
}
},
// 发送文字消息
sendText(){
this.hideDrawer();//隐藏抽屉
if(!this.textMsg){
return;
}
let msg = {
contentType: 1,
content: this.textMsg,
};
this.$emit('send', msg);
this.textMsg = '';//清空输入框
},
//替换表情符号为图片
replaceEmoji(str){
let replacedStr = str.replace(/\[([^(\]|\[)]*)\]/g,(item, index)=>{
console.log("item: " + item);
for(let i=0;i<this.emojiList.length;i++){
let row = this.emojiList[i];
for(let j=0;j<row.length;j++){
let EM = row[j];
if(EM.alt==item){
//在线表情路径图文混排必须使用网络路径请上传一份表情到你的服务器后再替换此路径
//比如你上传服务器后你的100.gif路径为https://www.xxx.com/emoji/100.gif 则替换onlinePath填写为https://www.xxx.com/emoji/
let onlinePath = 'https://s2.ax1x.com/2019/04/12/'
let imgstr = '<img src="'+onlinePath+this.onlineEmoji[EM.url]+'">';
console.log("imgstr: " + imgstr);
return imgstr;
}
}
}
});
return '<div style="display: flex;align-items: center;word-wrap:break-word;">'+replacedStr+'</div>';
},
voiceOk(e) {
this.$emit('voiceOk', e);
},
// 打开抽屉
openDrawer(){
this.popupLayerClass = 'showLayer';
},
//更多功能(点击+弹出)
showMore(){
this.isVoice = true;
this.hideEmoji = true;
if(this.hideMore){
this.hideMore = false;
this.openDrawer();
}else{
this.hideDrawer();
}
},
// 隐藏抽屉
hideDrawer(){
this.popupLayerClass = '';
this.hideMore = true;
this.hideEmoji = true;
this.isVoice = true;
},
// 选择表情
chooseEmoji(){
this.emojiList = emoji;
this.isVoice = true;
this.hideMore = true;
if(this.hideEmoji){
this.hideEmoji = false;
this.openDrawer();
}else{
this.hideDrawer();
}
},
// 切换语音/文字输入
switchVoice(){
this.hideEmoji = true;
this.hideMore = true;
if(this.isVoice){
this.isVoice = false;
this.openDrawer();
}else{
this.hideDrawer();
}
},
// 录音开始
voiceBegin(e){
this.timeOutEvent = setTimeout(() => {
this.longPress(e); //长按方法
}, 500); //这里设置定时器定义长按500毫秒触发长按事件
return false;
},
longPress(e) {
if(e.touches.length>1){
return ;
}
this.initPoint.Y = e.touches[0].clientY;
this.initPoint.identifier = e.touches[0].identifier;
this.RECORDER.start({format:"mp3"});//录音开始,
},
//录音开始UI效果
recordBegin(e){
this.recording = true;
this.voiceTis='松开 结束';
this.recordLength = 0;
this.recordTimer = setInterval(()=>{
this.recordLength++;
},1000)
},
// 录音被打断
voiceCancel(){
clearTimeout(this.timeOutEvent); //清除定时器
this.timeOutEvent = 0;
this.recording = false;
this.voiceTis='按住 说话';
this.recordTis = '手指上滑 取消发送'
this.willStop = true;//不发送录音
this.RECORDER.stop();//录音结束
},
// 录音中(判断是否触发上滑取消发送)
voiceIng(e){
clearTimeout(this.timeOutEvent); //清除定时器
this.timeOutEvent = 0;
if(!this.recording){
return;
}
let touche = e.touches[0];
//上滑一个导航栏的高度触发上滑取消发送
if(this.initPoint.Y - touche.clientY>=uni.upx2px(100)){
this.willStop = true;
this.recordTis = '松开手指 取消发送'
}else{
this.willStop = false;
this.recordTis = '手指上滑 取消发送'
}
},
// 结束录音
voiceEnd(e){
clearTimeout(this.timeOutEvent); //清除定时器
if(!this.recording){
return;
}
this.recording = false;
this.voiceTis='按住 说话';
this.recordTis = '手指上滑 取消发送'
this.RECORDER.stop();//录音结束
},
//录音结束(回调文件)
recordEnd(e){
clearInterval(this.recordTimer);
if(!this.willStop){
console.log("e: " + JSON.stringify(e));
let msg = {
length:0,
url:e.tempFilePath
}
let min = parseInt(this.recordLength/60);
let sec = this.recordLength%60;
min = min<10?'0'+min:min;
sec = sec<10?'0'+sec:sec;
msg.length = min+':'+sec;
this.$emit('send', msg, 'voice');
}else{
console.log('取消发送录音');
}
this.willStop = false;
},
isPhoneX() {
const res = uni.getSystemInfoSync();
let iphonex = false;
let models = ['iphonex', 'iphonexr', 'iphonexsmax', 'iphone11', 'iphone11pro', 'iphone11promax']
const model = res.model.replace(/\s/g, "").toLowerCase()
if (models.includes(model)) {
iphonex = true;
}
return iphonex;
},
// 选择图片发送
chooseImage() {
this.getImage('album');
},
//拍照发送
camera() {
this.getImage('camera');
},
getWeixin() {
var that = this;
uni.showModal({
title: '交换名片',
content: '确认交换名片吗',
success: function (res) {
if (res.confirm) {
that.$emit('getWeixin');
}
},
});
},
//选照片 or 拍照
getImage(type) {
this.hideDrawer();
uni.chooseImage({
count: 9,
sourceType: [type],
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
success: (res) => {
for (let i = 0; i < res.tempFilePaths.length; i++) {
uni.getImageInfo({
src: res.tempFilePaths[i],
success: (image) => {
let msg = {
path: res.tempFilePaths[i],
imgWidth: image.width,
imgHeight: image.height
};
this.$emit('imageOk', msg);
}
});
}
}
});
},
discard(){
return;
}
}
};
</script>
<style lang="scss" scoped>
.voice-center {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
.hidden{
display: none !important;
}
.popup-layer{
position: relative;
&.showLayer{height: 570rpx;}
transition: all .15s linear;
width: 100%;
height: 0rpx;
background-color: #fff;
//position: fixed;
z-index: 20;
top: 100%;
.emoji-tools-scroll-view {
height: 110rpx;
.emoji-tool-box {
display: flex;
height: 100%;
padding: 0 10px;
align-items: center;
}
.emoji-tools-item {
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
padding: 0 10px;
border-radius: 10px;
margin-right: 10px;
.img {
height: 50rpx;
width: 50rpx;
position: absolute;
border-radius: 0;
}
.emoji {
width: 36.36rpx;
height: 36.36rpx !important;
margin: 5.45rpx 18.18rpx;
position: relative;
top: 3.63rpx;
}
}
.emoji-tools-item.select {
background: #eaeaea;
}
}
.del-btn {
position: fixed;
right: 10px;
bottom: 136rpx;
background-color: #fff;
border-radius: 6px;
display: flex;
justify-content: center;
align-items: center;
padding: 14rpx 20rpx;
box-shadow: 1px 1px 1px 1px #ddd;
}
.emoji-swiper{
height: 460rpx;
display: flex;
flex-direction: column;
.title {
margin-left: 30rpx;
font-size: 22rpx;
color: #333;
margin-bottom: 30rpx;
}
.emoji-list {
transform: translate(1%, -5px) translateZ(0px);
display: flex;
flex-wrap: wrap;
}
.emoji_tools1{
width: 14%;
display: flex;
justify-content: center;
padding-bottom: 10px;
text{
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 44rpx;
}
.icon{
width: 8.4vw;
height: 8.4vw;
}
}
.emoji_image{
width: 20%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin-bottom: 20rpx;
.emoji-add {
border: 1px dashed #333;
height: 100rpx;
width: 100rpx;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.image {
height: 100rpx;
width: 100rpx;
margin-bottom: 10rpx;
}
text {
font-size: 22rpx;
}
}
}
.tool-swiper{
height: 570rpx;
padding: 0px 40rpx;
.tool-swiper-box {
display: flex;
padding-top: 30rpx;
}
swiper-item{
display: flex;
align-content: flex-start;
flex-wrap: wrap;
.tool-btn {
padding-top: 10px;
display: flex;
flex-direction: column;
align-items: center;
width: 25%;
margin-bottom: 40rpx;
.btn-card {
background-color: #f5f5f5;
width: 110rpx;
height: 110rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
margin-bottom: 20rpx;
}
.btn-text {
font-size: 22rpx;
color: #333;
}
}
}
}
.more-layer{
width: 100%;
height: 42vw;
.list{
width: 100%;
display: flex;
flex-wrap: wrap;
.box{
width: 18vw;
height: 18vw;
border-radius: 20upx;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 0 3vw 2vw 3vw;
.icon{
font-size: 70upx;
}
}
}
}
}
.input-box{
min-height: 100upx;
left: 0;
right: 0;
background-color: #fff;
display: flex;
z-index: 20;
bottom:-2upx;
&.showLayer{}
transition: all .15s linear;
display: flex;
flex-direction: column;
padding: 0 5px;
.voice,.more{
flex-shrink: 0;
width: 90upx;
height: 100upx;
display: flex;
justify-content: center;
align-items: center;
}
.send{
//H5发送按钮左边距
margin-left: 20upx;
flex-shrink: 0;
display: flex;
align-items: center;
.btn{
width: 90upx;
height: 56upx;
display: flex;
justify-content: center;
align-items: center;
background-color: #e54d42;
color: #fff;
border-radius: 3px;
font-size: 24rpx;
}
}
.textbox{
width: 100%;
min-height: 70upx;
//margin-left: 8px;
.voice-mode{
width: calc(100% - 2upx);
height: 68upx;
border-radius: 6px;
border:solid 1upx #cdcdcd;
display: flex;
justify-content: center;
align-items: center;
font-size: 28upx;
background-color: #fff;
font-weight: bold;
color: #555;
&.recording{
background-color: #e5e5e5;
}
}
.text-mode{
width: 100%;
min-height: 70upx;
display: flex;
background-color: #F8F8F8;
border-radius: 45px;
color: #666666;
font-size: 12px;
.box{
width: 100%;
padding-left: 30upx;
min-height: 70upx;
display: flex;
align-items: center;
padding: 5px 10px;
textarea{
width: 100%;
}
}
.em{
flex-shrink: 0;
width: 80upx;
padding-left: 10upx;
height: 70upx;
display: flex;
justify-content: center;
align-items: center;
}
.input-placeholder {
color: #bfbfbf;
font-size: 12px;
}
}
}
}
.record{
width: 40vw;
height: 40vw;
position: fixed;
top: 55%;
left: 30%;
background-color: rgba(0,0,0,.6);
border-radius: 20upx;
.ing{
width: 100%;
height: 30vw;
display: flex;
justify-content: center;
align-items: center;
// 模拟录音音效动画
@keyframes volatility {
0% {background-position: 0% 130%;}
20% {background-position: 0% 150%;}
30% {background-position: 0% 155%;}
40% {background-position: 0% 150%;}
50% {background-position: 0% 145%;}
70% {background-position: 0% 150%;}
80% {background-position: 0% 155%;}
90% {background-position: 0% 140%;}
100% {background-position: 0% 135%;}
}
.icon{
background-image:linear-gradient(to bottom,#f09b37,#fff 50%);
background-size:100% 200%;
animation: volatility 1.5s ease-in-out -1.5s infinite alternate;
-webkit-background-clip:text;
-webkit-text-fill-color:transparent;
font-size: 150upx;
color: #f09b37;
}
}
.cancel{
width: 100%;
height: 30vw;
display: flex;
justify-content: center;
align-items: center;
.icon{
color: #fff;
font-size: 150upx;
}
}
.tis{
width: 100%;
height: 10vw;
display: flex;
justify-content: center;
font-size: 28upx;
color: #fff;
&.change{
color: #f09b37;
}
}
}
.content{
width: 100%;
.msg-list{
width: 96%;
padding: 0 2%;
position: absolute;
top: 0;
bottom: 100upx;
.loading{
//loading动画
display: flex;
justify-content: center;
@keyframes stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.6);
}
20% {
transform: scaleY(1.0);
}
}
.spinner {
margin: 20upx 0;
width: 60upx;
height: 100upx;
display: flex;
align-items: center;
justify-content: space-between;
view {
background-color: #f06c7a;
height: 50upx;
width: 6upx;
border-radius: 6upx;
animation: stretchdelay 1.2s infinite ease-in-out;
}
.rect2 {
animation-delay: -1.1s;
}
.rect3 {
animation-delay: -1.0s;
}
.rect4 {
animation-delay: -0.9s;
}
.rect5 {
animation-delay: -0.8s;
}
}
}
.row{
.system{
display: flex;
justify-content: center;
view{
padding: 0 30upx;
height: 50upx;
display: flex;
justify-content: center;
align-items: center;
background-color: #c9c9c9;
color: #fff;
font-size: 24upx;
border-radius: 40upx;
}
.red-envelope{
image{
margin-right: 5upx;
width: 30upx;
height: 30upx;
}
}
}
&:first-child{
margin-top: 20upx;
}
padding: 20upx 0;
.my .left,.other .right{
width: 100%;
display: flex;
.bubble{
max-width: 70%;
min-height: 50upx;
border-radius: 10upx;
padding: 15upx 20upx;
display: flex;
align-items: center;
font-size: 32upx;
word-break: break-word;
&.img{
background-color: transparent;
padding:0;
overflow: hidden;
image{
max-width: 350upx;
max-height: 350upx;
}
}
&.red-envelope{
background-color: transparent;
padding:0;
overflow: hidden;
position: relative;
justify-content: center;
align-items: flex-start;
image{
width: 250upx;
height: 313upx;
}
.tis{
position: absolute;
top: 6%;
font-size: 26upx;
color: #9c1712;
}
.blessing{
position: absolute;
bottom: 14%;
color: #e9b874;
width: 80%;
text-align: center;
overflow: hidden;
// 最多两行
display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;
}
}
&.voice{
.icon{
font-size: 40upx;
display: flex;
align-items: center;
}
.icon:after
{
content:" ";
width: 53upx;
height: 53upx;
border-radius: 100%;
position: absolute;
box-sizing: border-box;
}
.length{
font-size: 28upx;
}
}
}
}
.my .right,.other .left{
flex-shrink: 0;
width: 80upx;
height: 80upx;
image{
width: 80upx;
height: 80upx;
border-radius: 10upx;
}
}
.my{
width: 100%;
display: flex;
justify-content: flex-end;
.left{
min-height: 80upx;
align-items: center;
justify-content: flex-end;
.bubble{
background-color: #f06c7a;
color: #fff;
&.voice{
.icon{
color: #fff;
}
.length{
margin-right: 20upx;
}
}
&.play{
@keyframes my-play {
0% {
transform: translateX(80%);
}
100% {
transform: translateX(0%);
}
}
.icon:after
{
border-left: solid 10upx rgba(240,108,122,.5);
animation: my-play 1s linear infinite;
}
}
}
}
.right{
margin-left: 15upx;
}
}
.other{
width: 100%;
display: flex;
.left{
margin-right: 15upx;
}
.right{
flex-wrap: wrap;
.username{
width: 100%;
height: 45upx;
font-size: 24upx;
color: #999;
display: flex;
.name{
margin-right: 50upx;
}
}
.bubble{
background-color: #fff;
color: #333;
&.voice{
.icon{
color: #333;
}
.length{
margin-left: 20upx;
}
}
&.play{
@keyframes other-play {
0% {
transform: translateX(-80%);
}
100% {
transform: translateX(0%);
}
}
.icon:after
{
border-right: solid 10upx rgba(255,255,255,.8);
animation: other-play 1s linear infinite;
}
}
}
}
}
}
}
}
.windows{
.mask{
position: fixed;
top: 100%;
width: 100%;
height: 100%;
z-index: 1000;
background-color: rgba(0,0,0,.6);
opacity: 0;
transition: opacity .2s ease-out;
}
.layer{
position: fixed;
width: 80%;
height: 70%;
left: 10%;
z-index: 1001;
border-radius: 20upx;
overflow: hidden;
top:100%;
transform: scale3d(.5,.5,1);
transition: all .2s ease-out;
}
&.show{
display: block;
.mask{
top: 0;
opacity: 1;
}
.layer{
transform: translate3d(0,-85vh,0) scale3d(1,1,1);
}
}
&.hide{
display: block;
.mask{
top: 0;
opacity: 0;
}
.layer{
//transform: translate3d(0,-85vh,0) scale3d(.5,.5,1);
}
}
}
.open-redenvelope{
width: 100%;
height: 70vh;
background-color: #cf3c35;
position: relative;
.top{
width: 100%;
background-color: #fe5454;
display: flex;
justify-content: center;
flex-wrap: wrap;
border-radius: 0 0 100% 100%;
box-shadow: inset 0 -20upx 0 #9c1712;
.close-btn{
width: 100%;
height: 80upx;
display: flex;
justify-content: flex-end;
margin-bottom: 30upx;
.icon{
color: #9c1712;
margin-top: 10upx;
margin-right: 10upx;
}
}
image{
width: 130upx;
height: 130upx;
border: solid 12upx #cf3c35;
border-radius: 100%;
margin-bottom: -65upx;
}
margin-bottom: 65upx;
}
.from,.blessing,.money,.showDetails{
width: 90%;
padding: 5upx 5%;
display: flex;
justify-content: center;
font-size: 32upx;
color: #fff;
}
.money{
font-size: 100upx;
color: #f8d757;
display: flex;
padding-top: 20upx;
}
.showDetails{
position: absolute;
bottom: 20upx;
align-items: center;
font-size: 28upx;
color: #f8d757;
.icon{
font-size: 26upx;
color: #f8d757;
}
}
}
.send-box {
display: flex;
flex: 1;
padding: 30rpx 20rpx;
align-items: center;
.icon {
padding-left: 8px;
}
}
.tool-box {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.send-tool {
display: flex;
justify-content: space-between;
padding: 15px;
padding-top: 0px;
}
</style>