<template>
  <div class="LiveBroadcast" @touchend="onTouchend" @touchmove="onTouchmove">
    <div class="top">
      <h2>请选择设备</h2>
      <image src="./img/right.png" />
    </div>
    <div class="middle">
      <div class="record" v-if="isShowRecord">
        <h2>喊话记录</h2>
        <scroll-view scroll-y class="record-wrapper">
          <div class="record-item" v-for="(item, index) in 100" :key="index">
            <image :src="user.avatar" />
            <div class="right">
              <!-- <image mode="aspectFit" src="./img/voice-icon.png" /> -->
              <image src="./img/voice.gif" />
              <span>23"</span>
            </div>
          </div>
        </scroll-view>
      </div>
      <div class="tips">
        <image src="./img/body.png" />
        <p>请先选择设备再按住下方按钮开始喊话~</p>
      </div>
    </div>
    <div class="bottom" @touchstart="onLongtap">
      <image src="./img/microphone.png" />
      <p>按住说话</p>
    </div>
    <div class="voice" :class="[isShow ? 'active' : '']">
      <div class="voice-bottom">
        <image src="./img/voice-w.png" />
      </div>
      <image class="close" :class="[isImpact ? 'close-active' : '']" :src="isImpact ? closeW : close" />
      <p>松开发送</p>
      <div class="header-line">
        <span class="line1 animation"></span>
        <span class="line2 animation"></span>
        <span class="line3 animation"></span>
        <span class="line4 animation"></span>
        <span class="line5 animation"></span>
        <span class="line6 animation"></span>
        <span class="line7 animation"></span>
        <span class="line8 animation"></span>
        <span class="line9 animation"></span>
        <span class="line10 animation"></span>
        <span class="line11 animation"></span>
        <span class="line12 animation"></span>
        <span class="line13 animation"></span>
        <span class="line14 animation"></span>
        <span class="line15 animation"></span>
        <span class="line16 animation"></span>
        <span class="line17 animation"></span>
        <span class="line18 animation"></span>
        <span class="line19 animation"></span>
        <span class="line20 animation"></span>
      </div>
      <h2>{{ time }}</h2>
    </div>
  </div>
</template>

<script>
  import { mapState } from 'vuex'
  import Recorder from 'recorder-core'
  import 'recorder-core/src/engine/mp3'
  import 'recorder-core/src/engine/mp3-engine'
  export default {
    name: 'LiveBroadcast',

    appName: '实时喊话',

    data () {
      return {
        x: 0,
        y: 0,
        w: 0,
        h: 0,
        isShowRecord: true,
        close: require('./img/close.png'),
        closeW: require('./img/close-w.png'),
        isShow: false,
        isImpact: false,
        startTime: 0,
        isRecording: false,
        recorder: null,
        blobFile: null,
        counterDownTime: 0,
        time: '00:00:00',
        timingTimeout: null
      }
    },

    computed: {
      ...mapState(['user'])
    },

    mounted () {

      const close = document.querySelector('.close')
      this.x = close.offsetLeft
      this.y = close.offsetTop
      this.w = close.clientWidth
      this.h = close.clientHeight
    },

    methods: {
      onLongtap () {
        this.isImpact = false
        this.startTime = new Date().getTime()
        this.isShow = true
        this.record()
      },

      record () {
        this.duration = 0
        this.recorder = Recorder({
          type: 'mp3',
          sampleRate: 16000,
          bitRate: 16,
          onProcess(buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
            //可利用extensions/waveview.js扩展实时绘制波形
          }
        })

        this.recorder.open(() => {
          this.recorder.start()
          this.timing()
        })
      },

      timing () {
        var durationObj = this.$dayjs.duration(this.counterDownTime * 1000)
        var hours = durationObj.hours() > 9 ? durationObj.hours() : '0' + durationObj.hours()
        var min = durationObj.minutes() > 9 ? durationObj.minutes() : '0' + durationObj.minutes()
        var seconds = durationObj.seconds() > 9 ? durationObj.seconds() : '0' + durationObj.seconds()

        this.time = hours + ':' + min + ':' + seconds
        this.counterDownTime++
        this.timingTimeout = setTimeout(() => {
          this.timing()
        }, 1000)
      },

      stop (isCancel) {
        this.counterDownTime = 0
        clearTimeout(this.timingTimeout)
        this.recorder.stop((blob, duration) => {
          this.recorder.close()
          this.recorder = null

          if (!isCancel) {
            this.blobFile = blob
          }

          this.time = '00:00:00'
          console.log(blob, (window.URL || webkitURL).createObjectURL(blob), '时长:' + duration + 'ms')
        }, msg => {
          console.log('录音失败:' + msg)
          this.recorder.close()
          this.recorder = null
        })
      },

      onTouchend () {
        if (this.isShow && new Date().getTime() - this.startTime < 1500) {
          this.isImpact = false
          this.isShow = false
          this.stop(true)
          return this.$u.toast('说话时间太短')
        }

        if (this.isImpact) {
          this.isShow = false
          this.isImpact = false
          this.stop(true)
          return false
        }

        this.isImpact = false
        this.stop()
      },

      onTouchmove (e) {
        if (this.isShow) {
          const x = e.touches[0].clientX
          const y = e.touches[0].clientY

          if (x >= this.x && x <= this.x + this.w && y >= this.y && y <= this.y + this.h) {
            this.isImpact = true
          } else {
            this.isImpact = false
          }
        }
      },

      submit () {

      }
    }
  }
</script>

<style lang="scss" scoped>
  .LiveBroadcast {
    height: 100vh;
    overflow: hidden;
    user-select: none;
    background: #F6F8FC;

    .voice {
      display: flex;
      position: fixed;
      flex-direction: column-reverse;
      align-items: center;
      top: 0;
      left: 0;
      z-index: -1;
      width: 100%;
      height: 100%;
      text-align: center;
      opacity: 0;
      background: rgba(0, 0, 0, 0.67);
      transition: all ease 0.5s;

      &.active {
        z-index: 1111111111111;
        opacity: 1;
      }

      .voice-bottom {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 234px;
        margin-top: 48px;
        border-radius: 200px 200px 0 0;
        background: linear-gradient(180deg, #9D9E9F 0%, #D4D5D6 100%);

        image {
          width: 96px;
          height: 96px;
        }
      }

      .header-line {
        display: flex;
        position: relative;
        align-items: center;
        justify-content: center;
        width: 322px;
        height: 164px;
        padding: 0 20px;
        border-radius: 20px;
        background: #86B7FF;

        &::after {
          position: absolute;
          bottom: 0;
          left: 50%;
          z-index: 1;
          width: 0;
          height: 0;
          border-top: 18px solid #86B7FF;
          border-right: 18px solid transparent;
          border-left: 18px solid transparent;
          content: ' ';
          transform: translate(-50%, 100%);
        }

        span {
          display: inline-block;
          width: 6px;
          height: 10px;
          margin: 0 6px;
          border: none;
          border-radius: 4px;
          background-color: #4B7CC3;
        }
      }

      h2 {
        margin-bottom: 48px;
        font-weight: 400;
        font-size: 96px;
        color: #A2A3A4;
        line-height: 134px;
      }

      & > p {
        margin: 48px;
        color: #A2A3A4;
        font-size: 28px;
      }

      & > image {
        width: 132px;
        height: 132px;
        transition: all ease 0.3s;
      }

      .close-active {
        transform: scale(1.1);
      }
    }

    .top {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 128px;
      padding: 0 32px;

      h2 {
        color: #333333;
        font-size: 32px;
        font-weight: 600;
      }

      image {
        width: 32px;
        height: 32px;
      }
    }

    .middle {
      height: calc(100% - 378px);
      background: #fff;

      .tips {
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        height: 100%;

        image {
          width: 406px;
          height: 306px;
          margin-bottom: 40px;
        }

        p {
          width: 346px;
          font-size: 30px;
          font-weight: 400;
          color: #999999;
          line-height: 42px;
          text-align: center;
        }
      }

      .record {
        height: 100%;

        & > h2 {
          height: 116px;
          line-height: 116px;
          padding: 0 32px;
          font-size: 38px;
          font-weight: 600;
          color: #333333;
          background: #FFFFFF;
        }

        .record-wrapper {
          height: calc(100% - 116px);
          padding: 0 32px;

          .record-item {
            display: flex;
            position: relative;
            align-items: center;
            margin-bottom: 32px;

            &:last-child {
              margin-bottom: 0;
              padding-bottom: 32px;
            }

            & > image {
              width: 76px;
              height: 76px;
              margin-right: 26px;
              border-radius: 8px;
            }

            .right {
              display: flex;
              align-items: center;
              position: relative;
              height: 74px;
              padding: 0 32px;
              border-radius: 12px;
              min-width: 160px;
              max-width: 100%;
              background: #C0DAFF;

              &::after {
                position: absolute;
                top: 50%;
                left: 0;
                z-index: 1;
                width: 0;
                height: 0;
                border-right: 12px solid #C0DAFF;
                border-left: 12px solid transparent;
                border-bottom: 12px solid transparent;
                border-top: 12px solid transparent;
                content: " ";
                transform: translate(-100%, -50%);
              }

              image {
                width: 28px;
                height: 28px;
                margin-right: 14px;
              }
            }
          }
        }
      }
    }

    .bottom {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      height: 250px;

      image {
        width: 128px;
        height: 128px;
        margin-bottom: 16px;
        pointer-events: none;
      }

      p {
        color: #333333;
        font-size: 30px;
      }
    }

    .animation {
      animation: note 0.24s ease-in-out;
      animation-iteration-count: infinite;
      animation-direction: alternate;
    }

    @keyframes note {
      from {
        transform: scaleY(1);
      }
      to {
        transform: scaleY(4);
      }
    }

    .header-line span.line1 {
      animation-delay: -1s;
    }

    .header-line span.line2 {
      animation-delay: -0.9s;
    }

    .header-line span.line3 {
      animation-delay: -0.8s;
    }

    .header-line span.line4 {
      animation-delay: -0.7s;
    }

    .header-line span.line5 {
      animation-delay: -0.6s;
    }

    .header-line span.line6 {
      animation-delay: -0.5s;
    }

    .header-line span.line7 {
      animation-delay: -0.4s;
    }

    .header-line span.line8 {
      animation-delay: -0.4s;
    }

    .header-line span.line9 {
      animation-delay: -0.2s;
    }

    .header-line span.line10 {
      animation-delay: -0.1s;
    }

    .header-line span.line11 {
      animation-delay: -1s;
    }

    .header-line span.line12 {
      animation-delay: -0.9s;
    }

    .header-line span.line13 {
      animation-delay: -0.8s;
    }

    .header-line span.line14 {
      animation-delay: -0.7s;
    }

    .header-line span.line15 {
      animation-delay: -0.6s;
    }

    .header-line span.line16 {
      animation-delay: -0.5s;
    }

    .header-line span.line17 {
      animation-delay: -0.4s;
    }

    .header-line span.line18 {
      animation-delay: -0.3s;
    }

    .header-line span.line19 {
      animation-delay: -0.2s;
    }

    .header-line span.line20 {
      animation-delay: -0.1s;
    }
  }
</style>
