uni-app 116发送语音功能
Posted 2019ab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app 116发送语音功能相关的知识,希望对你有一定的参考价值。
/common/free-lib/util.js
import $C from './config.js'
export default
// 获取存储列表数据
getStorage(key)
let data = null;
// #ifdef H5
if($C.env === 'dev')
data = window.sessionStorage.getItem(key)
else
data = uni.getStorageSync(key)
// #endif
// #ifndef H5
data = uni.getStorageSync(key)
// #endif
return data
,
// 设置存储
setStorage(key,data)
// #ifdef H5
if($C.env === 'dev')
return window.sessionStorage.setItem(key,data)
else
return uni.setStorageSync(key,data)
// #endif
// #ifndef H5
return uni.setStorageSync(key,data)
// #endif
,
// 删除存储
removeStorage(key)
// #ifdef H5
if($C.env === 'dev')
return window.sessionStorage.removeItem(key);
else
return uni.removeStorageSync(key)
// #endif
// #ifndef H5
return uni.removeStorageSync(key)
// #endif
/pages/chat/chat/chat.vue
<template>
<view>
<!-- 导航栏 -->
<free-nav-bar :title="detail.name" :noreadnum="totalNoreadnum" showBack>
<free-icon-button slot="right"
:icon="'\\ue6fd'"
@click="openChatSet"></free-icon-button>
</free-nav-bar>
<!-- 聊天内容区域 -->
<scroll-view scroll-y class="bg-light position-fixed left-0 right-0 px-3" style="bottom: 105rpx;box-sizing: border-box;" :style="chatBodyBottom" :show-scrollbar="false" :scroll-into-view="scrollIntoView" :scroll-with-animation="true"
@click="clickPage">
<!-- 聊天信息列表组件 -->
<view v-for="(item,index) in list" :key="index"
:id="'chatItem_'+index">
<free-chat-item :item="item" :index="index" ref="chatItem"
:pretime=" index > 0 ? list[index-1].create_time : 0"
@long="long" @preview="previewImage"
:shownickname="currentChatItem.shownickname"
></free-chat-item>
</view>
</scroll-view>
<!-- #ifdef APP-PLUS-NVUE -->
<div v-if="mode === 'action' || mode === 'emoticon'"
class="position-fixed top-0 right-0 left-0"
:style="'bottom:'+maskBottom+'px;'"
@click="clickPage"></div>
<!-- #endif -->
<!-- 底部输入框 -->
<view class="position-fixed left-0 right-0 border-top flex align-center" style="background-color: #F7F7F6;height: 105rpx;"
:style="'bottom:'+KeyboardHeight+'px;'">
<free-icon-button v-if="mode === 'audio'" @click="changeVoiceOrText"><text class="iconfont font-lg"></text></free-icon-button>
<free-icon-button v-else @click="changeVoiceOrText"><text class="iconfont font-lg"></text></free-icon-button>
<view class="flex-1">
<view v-if="mode === 'audio'" class="rounded flex align-center justify-center" style="height: 80rpx;" :class="isRecording?'bg-hover-light':'bg-white'" @touchstart="voiceTouchStart" @touchend="voiceTouchEnd" @touchcancel="voiceTouchCancel" @touchmove="voiceTouchMove">
<text class="font">isRecording ? '松开 结束':'按住 说话'</text>
</view>
<textarea v-else fixed class="bg-white rounded p-2 font-md" style="height: 50rpx;max-width: 450rpx;" :adjust-position="false" v-model="text" @focus="mode = 'text'"/>
</view>
<!-- 表情 -->
<free-icon-button
@click="openActionOrEmoticon('emoticon')"><text class="iconfont font-lg"
></text></free-icon-button>
<template v-if="text.length === 0">
<!-- 扩展菜单 -->
<free-icon-button
@click="openActionOrEmoticon('action')"><text class="iconfont font-lg"
></text></free-icon-button>
</template>
<view v-else class="flex-shrink">
<!-- 发送按钮 -->
<free-main-button name="发送"
@click="send('text')"></free-main-button>
</view>
</view>
<!-- 扩展菜单 -->
<free-popup ref="action" bottom transformOrigin="center bottom" @hide="KeyboardHeight = 0" :mask="false">
<view style="height: 580rpx;" class="border-top border-light-secondary bg-light">
<swiper :indicator-dots="emoticonOrActionList.length > 1" style="height: 510rpx;">
<swiper-item class="row"
v-for="(item,index) in emoticonOrActionList"
:key="index">
<view class="col-3 flex flex-column align-center justify-center" style="height: 255rpx;" v-for="(item2,index2) in item" :key="index2" @click="actionEvent(item2)">
<image :src="item2.icon" mode="widthFix"
style="width: 100rpx;height: 100rpx;"></image>
<text class="font-sm text-muted mt-2"
>item2.name</text>
</view>
</swiper-item>
</swiper>
</view>
</free-popup>
<!-- 弹出层 -->
<free-popup ref="extend" :bodyWidth="240" :bodyHeight="450" :tabbarHeight="105">
<view class="flex flex-column"
style="width: 240rpx;"
:style="getMenusStyle">
<view class="flex-1 flex align-center"
hover-class="bg-light"
v-for="(item,index) in menusList"
:key="index"
@click="clickEvent(item.event)">
<text class="font-md pl-3">item.name</text>
</view>
</view>
</free-popup>
<!-- 录音提示 -->
<view v-if="isRecording" class="position-fixed top-0 left-0 right-0 flex align-center justify-center" style="bottom: 105rpx;">
<view style="width: 360rpx;height: 360rpx;background-color: rgba(0,0,0,0.5);" class="rounded flex flex-column align-center justify-center">
<image src="/static/images/audio/audio/recording.gif" style="width: 150rpx;height: 150rpx;"></image>
<text class="font text-white mt-3">unRecord ? '松开手指,取消发送':'手指上滑,取消发送'</text>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-PLUS-NVUE
const dom = weex.requireModule('dom')
// #endif
import freeNavBar from "@/components/free-ui/free-nav-bar.vue"
import freeIconButton from "@/components/free-ui/free-icon-button.vue"
import freeChatItem from '@/components/free-ui/free-chat-item.vue';
import freePopup from "@/components/free-ui/free-popup.vue"
import freeMainButton from '@/components/free-ui/free-main-button.vue';
import mapState,mapMutations from 'vuex'
import auth from '@/common/mixin/auth.js';
import $U from '@/common/free-lib/util.js';
import $H from '@/common/free-lib/request.js';
import $C from '@/common/free-lib/config.js';
export default
mixins:[auth],
components:
freeNavBar,
freeIconButton,
freeChatItem,
freePopup,
freeMainButton
,
data()
return
scrollIntoView:"",
// 模式 text输入文字,emoticon表情,action操作,audio音频
mode:"text",
// 扩展菜单列表
actionList:[
[
name:"相册",
icon:"/static/images/extends/pic.png",
event:"uploadImage"
,
name:"拍摄",
icon:"/static/images/extends/video.png",
event:"uploadVideo"
,
name:"收藏",
icon:"/static/images/extends/shoucan.png",
event:"openFava"
,
name:"名片",
icon:"/static/images/extends/man.png",
event:"sendCard"
,
name:"语音通话",
icon:"/static/images/extends/phone.png",
event:""
,
name:"位置",
icon:"/static/images/extends/path.png",
event:""
]
],
emoticonList:[],
// 键盘高度
KeyboardHeight:0,
menusList:[],
navBarHeight:0,
list:[],
// 当前操作的气泡索引
propIndex:-1,
// 输入文字
text:"",
// 音频录制状态
isRecording:false,
RecordingStartY:0,
// 取消录音
unRecord:false,
detail:
id:0,
name:"",
avatar:"",
chat_type:"user"
,
mounted()
var statusBarHeight = 0
// #ifdef APP-PLUS-NVUE
statusBarHeight = plus.navigator.getStatusbarHeight()
// #endif
this.navBarHeight = statusBarHeight + uni.upx2px(90)
// 监听键盘高度变化
uni.onKeyboardHeightChange(res =>
if (this.mode !== 'action' && this.mode !== 'emoticon')
this.KeyboardHeight = res.height
if (this.KeyboardHeight > 0)
this.pageToBottom()
)
// 注册发送音频事件
this.regSendVoiceEvent((url)=>
if (!this.unRecord)
this.send('audio',url,
time:this.RecordTime
)
)
this.pageToBottom()
,
computed:
...mapState(
chatList:state=>state.user.chatList,
RECORD:state=>state.audio.RECORD,
RecordTime:state=>state.audio.RecordTime,
chat:state=>state.user.chat,
totalNoreadnum:state=>state.user.totalNoreadnum,
user:state=>state.user.user
),
// 当前会话配置信息
currentChatItem()
let index = this.chatList.findIndex(item=>item.id === this.detail.id && item.chat_type === this.detail.chat_type)
if(index !== -1)
return this.chatList[index]
return
,
// 获取蒙版的位置
maskBottom()
return this.KeyboardHeight + uni.upx2px(105)
,
// 动态获取菜单高度
getMenusHeight()
let H = 100
return this.menusList.length * H
,
// 获取菜单的样式
getMenusStyle()
return `height: $this.getMenusHeightrpx;`
,
// 判断是否操作本人信息
isdoSelf()
// 获取本人id(假设拿到了)
let id = 1
let user_id = this.propIndex > -1 ? this.list[this.propIndex].user_id : 0
return user_id === id
,
// 聊天区域bottom
chatBodyBottom()
return `bottom:$uni.upx2px(105) + this.KeyboardHeightpx;top:$this.navBarHeightpx;`
,
// 获取操作或者表情列表
emoticonOrActionList()
return (this.mode === 'emoticon' || this.mode === 'action') ? this[this.mode+'List'] : []
,
// 所有信息的图片地址
imageList()
let arr = []
this.list.forEach((item)=>
if (item.type === 'emoticon' || item.type === 'image')
arr.push(item.data)
)
return arr
,
watch:
mode(newValue, oldValue)
if (newValue !== 'action' && newValue !== 'emoticon')
this.$refs.action.hide()
if (newValue !== 'text')
uni.hideKeyboard()
,
onLoad(e)
if(!e.params)
return this.backToast()
this.detail = JSONiOS - 语音云通讯