123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- const MIN_VOICE_TIME = 1, MAX_VOICE_TIME = 60, START_TIME_DOWN = 54, status = {
- START: 1,
- SUCCESS: 2,
- CANCEL: 3,
- SHORT: 4,
- FAIL: 5,
- UNAUTH: 6
- }, EVENT = {
- EXTRA_CLICK: 'extraClickEvent',
- EXTRA_ITEM_CLICK: 'extraItemClickEvent',
- VOICE_RECORD: 'voiceRecordEvent',
- SEND_MESSAGE: 'sendMessageEvent'
- };
- Component({
- properties: {
- minVoiceTime: {
- type: Number,
- value: MIN_VOICE_TIME
- },
- maxVoiceTime: {
- type: Number,
- value: MAX_VOICE_TIME
- },
- startTimeDown: {
- type: Number,
- value: START_TIME_DOWN,
- },
- tabBarHeight: {
- type: Number,
- value: 0
- },
- format: {
- type: String,
- value: 'mp3'
- },
- extraArray: {
- type: Array,
- value: []
- }
- },
- data: {
- windowHeight: 0,
- windowWidth: 0,
- cancelLineYPosition: 0,
- _startTimeDown: START_TIME_DOWN,
- timer: -1,
- singleVoiceTimeCount: 0,
- textMessage: '',
- voiceObj: {moveToCancel: false},
- extraObj: {
- chatInputShowExtra: false,
- chatInputExtraArr: []
- },
- inputStatus: 'text',
- inputValueEventTemp: ''
- },
- observers: {
- 'extraArray'(value) {
- this.setData({
- 'extraObj.chatInputExtraArr': value || []
- })
- },
- 'startTimeDown'(startTimeDown) {
- const data = this.data;
- data._startTimeDown = startTimeDown && startTimeDown < data.maxVoiceTime && startTimeDown > 0 ? startTimeDown : START_TIME_DOWN;
- }
- },
- methods: {
- getRecordStatus() {
- return {...status};
- },
- closeExtraView() {
- this.setData({
- 'extraObj.chatInputShowExtra': false
- });
- },
- _chatInput$extra$click$event() {
- const isShow = !this.data.extraObj.chatInputShowExtra;
- this.setData({
- 'extraObj.chatInputShowExtra': isShow
- }, () => {
- this.triggerEvent(EVENT.EXTRA_CLICK, {isShow}, {});
- });
- },
- _change$input$way$event() {
- this.setData({
- 'inputStatus': this.data.inputStatus === 'text' ? 'voice' : 'text',
- 'extraObj.chatInputShowExtra': false
- });
- },
- _triggerVoiceRecordEvent({status, dataset}) {
- this.triggerEvent(EVENT.VOICE_RECORD, {recordStatus: status, ...dataset}, {});
- },
- _long$click$voice$btn(e) {
- if ('send$voice$btn' === e.currentTarget.id) {//长按时需要打开录音功能,开始录音
- this._checkRecordAuth(() => {
- const {maxVoiceTime, singleVoiceTimeCount} = this.data;
- this.setData({//调出取消弹窗
- 'voiceObj.showCancelSendVoicePart': true,
- 'voiceObj.timeDownNum': maxVoiceTime - singleVoiceTimeCount,
- 'voiceObj.status': 'start',
- 'voiceObj.startStatus': 1,
- 'voiceObj.moveToCancel': false
- }, () => {
- this._triggerVoiceRecordEvent({status: status.START});
- });
- this.recorderManager.start({duration: 60000, format: this.data.format});
- }, (res) => {
- //录音失败
- console.error('录音拒绝授权');
- clearInterval(timer);
- this._endRecord();
- this.setData({
- 'voiceObj.status': 'end',
- 'voiceObj.showCancelSendVoicePart': false
- });
- this._triggerVoiceRecordEvent({status: status.UNAUTH});
- wx.showModal({
- title: '您未授权语音功能',
- content: '暂时不能使用语音',
- confirmText: '去设置',
- success: res => {
- if (res.confirm) {
- wx.openSetting({
- success: res => {
- if (res.authSetting['scope.record']) {
- this.setData({
- 'extraObj.chatInputShowExtra': false
- });
- }
- }
- });
- } else {
- this.setData({
- 'inputStatus': 'text',
- 'extraObj.chatInputShowExtra': false
- });
- }
- }
- });
- });
- }
- },
- _dealVoiceLongClickEventWithHighVersion() {
- this.recorderManager.onStart(() => {
- this.data.singleVoiceTimeCount = 0;
- const {_startTimeDown, maxVoiceTime} = this.data;
- //设置定时器计时60秒
- this.data.timer = setInterval(() => {
- const voiceTimeCount = ++this.data.singleVoiceTimeCount;
- if (voiceTimeCount >= _startTimeDown && voiceTimeCount < maxVoiceTime) {
- this.setData({
- 'voiceObj.timeDownNum': maxVoiceTime - voiceTimeCount,
- 'voiceObj.status': 'timeDown'
- })
- } else if (voiceTimeCount >= maxVoiceTime) {
- this.setData({
- 'voiceObj.status': 'timeout'
- });
- this._delayDismissCancelView();
- clearInterval(this.data.timer);
- this._endRecord();
- }
- }, 1000);
- })
- },
- _send$voice$move$event(e) {
- if ('send$voice$btn' === e.currentTarget.id) {
- const {windowHeight, voiceObj, tabBarHeight, cancelLineYPosition} = this.data,
- y = windowHeight + tabBarHeight - e.touches[0].clientY;
- if (y > cancelLineYPosition) {
- if (!voiceObj.moveToCancel) {
- this.setData({
- 'voiceObj.moveToCancel': true
- });
- }
- } else {
- if (voiceObj.moveToCancel) {//如果移出了该区域
- this.setData({
- 'voiceObj.moveToCancel': false
- })
- }
- }
- }
- },
- _send$voice$move$end$event(e) {
- if ('send$voice$btn' === e.currentTarget.id) {
- const {singleVoiceTimeCount, minVoiceTime, timer} = this.data;
- if (singleVoiceTimeCount < minVoiceTime) {//语音时间太短
- this.setData({
- 'voiceObj.status': 'short'
- });
- this._delayDismissCancelView();
- } else {//语音时间正常
- this.setData({
- 'voiceObj.showCancelSendVoicePart': false,
- 'voiceObj.status': 'end'
- });
- }
- clearInterval(timer);
- this._endRecord();
- }
- },
- _initVoiceData() {
- const {windowWidth, windowHeight} = this.data, width = windowWidth / 2.6;
- this.setData({
- 'inputStatus': 'text',
- 'windowHeight': windowHeight,
- 'windowWidth': windowWidth,
- 'voiceObj.status': 'end',
- 'voiceObj.startStatus': 0,
- 'voiceObj.voicePartWidth': width,
- 'voiceObj.moveToCancel': false,
- 'voiceObj.voicePartPositionToBottom': (windowHeight - width / 2.4) / 2,
- 'voiceObj.voicePartPositionToLeft': (windowWidth - width) / 2
- });
- },
- _delayDismissCancelView() {
- setTimeout(() => {
- if (this.data.voiceObj.status !== 'start') {
- this.setData({
- 'voiceObj.showCancelSendVoicePart': false,
- 'voiceObj.status': 'end'
- });
- }
- }, 1000);
- },
- _endRecord() {
- this.setData({
- 'voiceObj.startStatus': 0
- }, () => {
- this.recorderManager.stop();
- });
- },
- _chatInput$bind$focus$event() {
- this.setData({
- 'inputType': 'text'
- })
- },
- _chatInput$send$text$message(e) {
- this.setData({
- textMessage: ''
- }, () => {
- this.triggerEvent(EVENT.SEND_MESSAGE, {value: e.detail.value});
- this.data.inputValueEventTemp = '';
- });
- },
- _chatInput$bind$blur$event() {
- setTimeout(() => {
- let obj = {};
- if (!this.data.inputValueEventTemp) {
- this.data.inputValueEventTemp = '';
- obj['inputType'] = 'none';
- }
- obj['extraObj.chatInputShowExtra'] = false;
- this.setData(obj);
- });
- },
- _chatInput$send$text$message02() {
- this.setData({
- textMessage: '',
- 'inputType': 'none'
- }, () => {
- if (!!this.data.inputValueEventTemp) {
- this.triggerEvent(EVENT.SEND_MESSAGE, {value: this.data.inputValueEventTemp});
- this.data.inputValueEventTemp = '';
- }
- });
- },
- _chatInput$getValue$event(e) {
- const {detail: {value: textMessage}} = e;
- this.data.inputValueEventTemp = textMessage;
- this.setData({
- textMessage
- })
- },
- _chatInput$extra$item$click$event(e) {
- const {currentTarget: {dataset}} = e;
- this.triggerEvent(EVENT.EXTRA_ITEM_CLICK, {...dataset}, {});
- },
- _setVoiceListener() {
- this.recorderManager.onStop((res) => {
- if (this.data.voiceObj.status === 'short') {//录音时间太短或者移动到了取消录音区域, 则取消录音
- this._triggerVoiceRecordEvent({status: status.SHORT});
- return;
- } else if (this.data.voiceObj.moveToCancel) {
- this._triggerVoiceRecordEvent({status: status.CANCEL});
- return;
- }
- this._triggerVoiceRecordEvent({status: status.SUCCESS, dataset: res});
- });
- this.recorderManager.onError((res) => {
- this._triggerVoiceRecordEvent({status: status.FAIL, dataset: res});
- });
- },
- _checkRecordAuth(cbOk, cbError) {
- wx.getSetting({
- success: (res) => {
- if (!res.authSetting['scope.record']) {
- wx.authorize({
- scope: 'scope.record',
- success: (res) => {
- // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
- // console.log('同意', res);
- }, fail: res => {
- // console.log('拒绝', res);
- cbError && cbError();
- }
- })
- } else {
- cbOk && cbOk();
- }
- }
- })
- }
- },
- lifetimes: {
- created() {
- this.recorderManager = wx.getRecorderManager();
- const {windowHeight, windowWidth} = wx.getSystemInfoSync();
- if (!windowHeight || !windowWidth) {
- console.error('没有获取到手机的屏幕尺寸:windowWidth', windowWidth, 'windowHeight', windowHeight);
- return;
- }
- this.data.windowHeight = windowHeight;
- this.data.windowWidth = windowWidth;
- this.data.cancelLineYPosition = windowHeight * 0.12;
- this._dealVoiceLongClickEventWithHighVersion();
- this._setVoiceListener();
- },
- attached() {
- this._initVoiceData();
- },
- detached() {
- clearInterval(this.data.timer);
- }
- }
- });
- // module.exports = {
- // clickExtraListener: clickExtraItemListener,
- // closeExtraView: closeExtraView,
- // recordVoiceListener: sendVoiceListener,
- // setVoiceRecordStatusListener: setVoiceRecordStatusListener,
- // setTextMessageListener: setTextMessageListener,
- // setExtraButtonClickListener: setExtraButtonClickListener,
- // VRStatus: status
- // };
|