<template>
  <view class="chat-record">
    <view class="chat-record-bar" :class="{ recording: recording }" id="chat-record-bar" @click.stop=""
          @touchstart.prevent="onStartRecord" @touchmove.prevent="onTouchMove" @touchend.prevent="onEndRecord">
      {{ recording ? '正在录音' : '长按 说话' }}</view>
    <view v-if="recording" class="chat-record-window" :style="recordWindowStyle">
      <view class="rc-wave">
        <text class="note" v-for="i in 7" :key="i" :style="{ animationDelay: (0.1 * (i - 1)) + 's' }"></text>
      </view>
      <view class="rc-tip">{{ recordTip }}</view>
      <view class="cancel-btn" @click="onCancel">
        <uni-icons :class="moveToCancel ? 'red' : 'black'" type="clear" :size="moveToCancel ? 45 : 40"></uni-icons>
      </view>
      <view class="opt-tip" :class="moveToCancel ? 'red' : 'black'">{{ moveToCancel ? '松手取消' : '松手发送,上划取消' }}</view>
    </view>
  </view>
</template>

<script>
export default {
  name: "chat-record",
  data() {
    return {
      recording: false,
      moveToCancel: false,
      recordBarTop: 0,
      duration: 0,
      rcTimer: null
    }
  },
  methods: {
    onTouchMove(e) {
      const moveY = e.touches[0].clientY;
      this.moveToCancel = moveY < this.recordBarTop - 40;
    },
    onCancel() {
      if (this.recording) {
        this.moveToCancel = true;
        this.onEndRecord();
      }
    },
    onStartRecord() {
      if (this.recording) {
        return;
      }
      console.log("开始录音")
      this.moveToCancel = false;
      this.initRecordBar();
      if (!this.$rc.checkIsEnable()) {
        return;
      }
      this.$rc.start().then(() => {
        this.recording = true;
        console.log("开始录音成功")
        this.startTimer();
      }).catch((e) => {
        console.log("录音失败" + JSON.stringify(e))
        uni.showToast({
          title: "录音失败",
          icon: "none"
        });
      });
    },
    onEndRecord() {
      if (!this.recording) {
        return;
      }
      this.recording = false;
      this.stopTimer();
      this.$rc.close();
      if (this.moveToCancel) {
        console.log("录音取消")
        return;
      }
      if (this.duration <= 1) {
        uni.showToast({
          title: "说话时间太短",
          icon: 'none'
        })
        return;
      }
      this.$rc.upload().then((data) => {
        this.$emit("send", data);
      }).catch((e) => {
        uni.showToast({
          title: e,
          icon: 'none'
        })
      })
    },
    startTimer() {
      this.duration = 0;
      this.stopTimer();
      this.rcTimer = setInterval(() => {
        this.duration++;
        if (this.duration >= 60) {
          this.onEndRecord();
        }
      }, 1000)
    },
    stopTimer() {
      this.rcTimer && clearInterval(this.rcTimer);
      this.rcTimer = null;
    },
    initRecordBar() {
      const query = uni.createSelectorQuery().in(this);
      query.select('#chat-record-bar').boundingClientRect((rect) => {
        this.recordBarTop = rect.top;
      }).exec()
    }
  },
  computed: {
    recordWindowStyle() {
      const windowHeight = uni.getSystemInfoSync().windowHeight;
      const bottom = windowHeight - this.recordBarTop + 12;
      return `bottom:${bottom}px;`
    },
    recordTip() {
      if (this.duration > 50) {
        return `${60 - this.duration}s后将停止录音`;
      }
      return `录音时长:${this.duration}s`;
    }
  },
  // Vue 2 生命周期钩子
  beforeDestroy() {
    this.stopTimer();
    this.recording = false;
  }
}
</script>

<style lang="scss" scoped>
.chat-record {
  .rc-wave {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    position: relative;
    height: 80rpx;

    .note {
      background: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
      width: 4px;
      height: 50%;
      border-radius: 5rpx;
      margin-right: 4px;
      animation: loading 0.5s infinite linear;

      @keyframes loading {
        0% {
          background-image: linear-gradient(to right, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
          height: 20%;
          border-radius: 5rpx;
        }
        50% {
          background-image: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
          height: 80%;
          border-radius: 5rpx;
        }
        100% {
          background-image: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
          height: 20%;
          border-radius: 5rpx;
        }
      }
    }
  }

  .chat-record-bar {
    padding: 10rpx;
    margin: 10rpx;
    border-radius: 10rpx;
    text-align: center;
    box-shadow: $im-box-shadow;

    &.recording {
      background-color: $im-color-primary;
      color: #fff;
    }
  }

  .chat-record-window {
    position: fixed;
    left: 0;
    right: 0;
    height: 360rpx;
    background-color: rgba(255, 255, 255, 0.95);
    padding: 30rpx;

    .icon-microphone {
      text-align: center;
      font-size: 80rpx;
      padding: 10rpx;
    }

    .rc-tip {
      text-align: center;
      font-size: $im-font-size-small;
      color: $im-text-color-light;
      margin-top: 20rpx;
    }

    .cancel-btn {
      text-align: center;
      margin-top: 40rpx;
      height: 80rpx;
    }

    .opt-tip {
      text-align: center;
      font-size: 30rpx;
      padding: 20rpx;
    }

    .red {
      color: $im-color-danger !important;
    }
  }
}
</style>
