Files
peiwan-uniapp/pages/im/components/chatBar.vue

1453 lines
36 KiB
Vue
Raw Normal View History

2025-01-21 01:46:34 +08:00
<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>