<template>
  <button class="cu-btn voice-btn" v-if="!disabled" ref="v-btn"
          :class="voice.recording ? 'active' : ''"
          @touchstart.stop.prevent="startVoice" @touchmove.stop.prevent="moveVoice" @touchend.stop="endVoice"
          @touchcancel.stop="cancelVoice">
    {{ voice.voiceTitle }}
  </button>
  <button class="cu-btn" v-if="disabled" ref="v-btn"
          :style="{ background: voice.recording ? '#c7c6c6' : '#FFFFFF',flex:'1' }">
    {{ times }}秒后可录音
  </button>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref} from "vue";
import MessageType from "@/utils/MessageType";
import upload from '@/api/UploadApi';
import MessageUtils from "@/utils/MessageUtils";

const disabled = ref(false);
const times = ref(5);
const interval = ref(-1);
const emit = defineEmits(["uploadCallback"]);
const voice = reactive({
  voiceTitle: '按住 说话',
  Recorder: uni.getRecorderManager(),
  recording: false,
  //标识是否正在录音
  isStopVoice: false,
  //加锁 防止点击过快引起的当录音正在准备(还没有开始录音)的时候,却调用了stop方法但并不能阻止录音的问题
  voiceInterval: -1,
  voiceTime: 0, //总共录音时长
  canSend: true, //是否可以发送
  PointY: 0, //坐标位置
  showFunBtn: false, //是否展示功能型按钮
  AudioExam: null //正在播放音频的实例
})

onMounted(() => {
  //录音开始事件
  voice.Recorder.onStart(() => {
    beginVoice();
  });
  //录音结束事件
  voice.Recorder.onStop(res => {
    clearInterval(voice.voiceInterval);
    if (voice.voiceTime >= 1) {
      handleRecorder(res);
    } else {
      voice.recording = false;
      MessageUtils.message('录音时间太短')
    }
  });

})


//准备开始录音
const startVoice = (e: TouchEvent) => {
  voice.recording = true;
  voice.isStopVoice = false;
  voice.canSend = true;
  voice.PointY = e.touches[0].clientY;

  voice.Recorder.start({
    format: 'mp3'
  });
}
//录音已经开始
const beginVoice = () => {
  uni.showLoading({
    title: '正在录音'
  })
  voice.voiceTitle = '松开 结束'
  voice.voiceInterval = setInterval(() => {
    voice.voiceTime++;
  }, 1000)
}
//move 正在录音中
const moveVoice = (e: TouchEvent) => {
  const pointY = e.touches[0].clientY
  const slideY = voice.PointY - pointY;
  if (slideY > uni.upx2px(120)) {
    voice.canSend = false;
  } else if (slideY > uni.upx2px(60)) {
    voice.canSend = true;
  }
}
//结束录音
const endVoice = () => {
  uni.hideLoading()
  voice.isStopVoice = true; //加锁 确保已经结束录音并不会录制
  setTimeout(function () {
    voice.Recorder.stop();
  }, 200)
  voice.voiceTitle = '按住 说话'
  disabled.value = true;
  setTimeout(function () {
    disabled.value = false;
    clearInterval(interval.value)
    times.value = 5;
  }, 5000)
  interval.value = setInterval(function () {
    times.value--;
  }, 1000)
}
//录音被打断
const cancelVoice = () => {
  voice.voiceTime = 0;
  voice.voiceTitle = '按住 说话';
  voice.canSend = false;
  voice.Recorder.stop();
}
//处理录音文件
const handleRecorder = ({tempFilePath}: any) => {
  voice.recording = false;
  uni.showLoading({
    title: '正在上传'
  })
  upload(tempFilePath)
      .then((res: any) => {
        const extend = {url: res.url, time: Math.ceil(voice.voiceTime)};
        voice.voiceTime = 0;
        emit('uploadCallback', extend, MessageType.voice)
      })
      .finally(() => {
        uni.hideLoading()
      })
}
</script>
<style scoped>
.voice-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  padding: 20upx;
  box-shadow: 0.0625rem 0.0625rem 0.1875rem rgba(0, 0, 0, .2);
  position: relative;
  margin: 0 .1875rem !important;
  height: 100%;
}

.voice-btn.active {
  background-color: #57d757;
  color: #ffffff;
}
</style>
