<template lang="pug">
div
  article.articleDetails
    .articleTitle
      | {{ Articels.post_title }}
    .articalMeta
      ul
        li
          Icon(:icon="['far', 'calendar-alt']")
          | &nbsp; {{ Articels.post_date }}
        li
          Icon(:icon="['far', 'bookmark']")
          nuxt-link(v-for='(relationships, index) in Articels.term_relationships', :key='index', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
            span
              | &nbsp; {{ relationships.term_taxonomy.term.name }}
        li(v-if='Articels.postmetum.meta_value !== 0')
          Icon(:icon="['fas', 'thermometer-' + Articels.hotValue]")
          | &nbsp; {{ Articels.postmetum.meta_value }}
    #articelToc.articelToc(v-if="Articels.post_toc_show")
      .articelTitle 目录
      .articelTocList(v-html="Articels.post_toc")
    .articelContent(v-html='Articels.post_content')
    ins.adsbygoogle(style="display:block; text-align:center; margin-top:20px;", data-ad-layout="in-article", data-ad-format="fluid", data-ad-client="ca-pub-2143583075951360", data-ad-slot="4741804954")
    .articelRightToc(v-show="Articels.post_toc_show && showRightToc", @click="articelRightTocClick")
      .articelTitle 目录
      .articelTocList(v-html="Articels.post_toc")
    p(style="margin: 15px 0;")
      img(src="https://cdn.wyr.me/imgs/reward.jpg" style="width: 100%")
    p(style="margin: 15px 0;") 评论功能已被暂时关闭，请通过 a@wyr.me 联系我。
  nuxt-link(:to="Articels.last ? '/post/' + Articels.last.ID : ''")
    .btnFooter.btnPrevt(:style="'color: ' + (Articels.last ? '#333' : '#ccc')")
      Icon(:icon="['fas', 'chevron-left']")
      | &nbsp; 上一篇 {{ Articels.last ? '(' + decodeTitle(Articels.last.post_name) + ')' : ''}}
  nuxt-link(:to="Articels.next ? '/post/' + Articels.next.ID : ''")
    .btnFooter.btnNext(:style="'color: ' + (Articels.next ? '#333' : '#ccc')")
      | 下一篇 {{ Articels.next ? '(' + decodeTitle(Articels.next.post_name) + ')' : ''}} &nbsp;
      Icon(:icon="['fas', 'chevron-right']")
  .comment

</template>

<script>
export default {
  async asyncData ({ route, app, $axios }) {
    const data = await $axios.$get(`/public/article/details?id=${route.params.id}`)
    const result = data.result
    result.post_date = app.$moment(result.post_date).utc().format('lll')// 格式化时间
    // 热度值计算
    if (result.postmetum !== null && result.postmetum !== '') {
      result.hotValue = app.$getHatValue(result.postmetum.meta_value)
    } else {
      result.hotValue = 0
      result.postmetum = {}
      result.postmetum.meta_value = 0
    }

    return {
      Articels: result,
      showRightToc: false,
      tocIds: result.post_toc_ids
    }
  },
  mounted () {
    this.$finishLoad()

    if (this.Articels.post_toc_show) {
      const tocShow = () => {
        if (window.addEvent) {
          window.addEvent(window, 'scroll', () => {
            const windowWidth = window.innerWidth || document.documentElement.clientWidth
            if (document.getElementById('articelToc') && !this.isOnScreen(document.getElementById('articelToc'))) {
              if (windowWidth < 768) {
                this.showRightToc = false
                document.getElementById('mobileToc').style.display = 'block'
              } else {
                this.showRightToc = true
              }
            } else {
              this.showRightToc = false
              if (windowWidth < 768) {
                document.getElementById('mobileToc').style.display = 'none'
              }
            }
          })
        } else {
          setTimeout(() => {
            tocShow()
          }, 50)
        }
      }
      tocShow()

      const tocIdsTop = []
      const tocIdsTopMap = new Map()
      for (const n in this.tocIds) {
        const tTop = document.getElementById(this.tocIds[n]).offsetTop
        tocIdsTop.push(tTop)
        tocIdsTopMap.set(tTop, '#' + this.tocIds[n])
      }

      const findInIds = (arr, num) => { for (let x = 0; x < arr.length; x++) { if (arr[x] > num) { return x - 1 } } }

      let debounce = null
      let lastIdInx = null

      const scrollToc = () => {
        let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
        const windowWidth = window.innerWidth || document.documentElement.clientWidth
        if (windowWidth < 768) { scrollTop = scrollTop * 2.7 + 175 }
        const tocIdsInx = findInIds(tocIdsTop, scrollTop + 130)
        if (tocIdsInx !== -1 && lastIdInx !== tocIdsInx && document.getElementsByClassName('articelRightToc')[0]) {
          const tocAList = document.getElementsByClassName('articelRightToc')[0].getElementsByTagName('a')
          const nowId = tocIdsTopMap.get(tocIdsTop[tocIdsInx])
          for (const i in tocAList) {
            if (tocAList[i] && tocAList[i].getAttribute && tocAList[i].getAttribute('href') === nowId) {
              tocAList[i].style.color = '#ff8a8a'
            } else if (tocAList[i] && tocAList[i].style) {
              tocAList[i].style.color = '#bbb'
            }
          }
          lastIdInx = tocIdsInx
        }
      }
      window.addEvent(window, 'scroll', () => {
        clearTimeout(debounce)
        debounce = setTimeout(() => {
          scrollToc()
        }, 20)
      })

      document.getElementById('mobileToc').onclick = () => {
        this.showRightToc = !this.showRightToc
      }
    }

    (adsbygoogle = window.adsbygoogle || []).push({}) // eslint-disable-line
  },
  methods: {
    decodeTitle (name) {
      try {
        return this.urldecode(name)
      } catch (err) {
        console.log(err)
        return name
      }
    },
    urldecode (encodedString) {
      let output = encodedString
      let binVal, thisString
      const myregexp = /(%[^%]{2})/
      function utf8to16 (str) {
        let c
        let char2, char3

        let out = ''
        const len = str.length
        let i = 0
        while (i < len) {
          c = str.charCodeAt(i++)
          switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
              out += str.charAt(i - 1)
              break
            case 12: case 13:
              char2 = str.charCodeAt(i++)
              out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F))
              break
            case 14:
              char2 = str.charCodeAt(i++)
              char3 = str.charCodeAt(i++)
              out += String.fromCharCode(((c & 0x0F) << 12) |
                ((char2 & 0x3F) << 6) |
                ((char3 & 0x3F) << 0))
              break
          }
        }
        return out
      }

      let match = null
      while ((match = myregexp.exec(output)) != null &&
        match.length > 1 &&
        match[1] !== '') {
        binVal = parseInt(match[1].substr(1), 16)
        thisString = String.fromCharCode(binVal)
        output = output.replace(match[1], thisString)
      }

      output = output.replace(/\\+/g, ' ')
      output = utf8to16(output)
      return output
    },
    articelRightTocClick () {
      const windowWidth = window.innerWidth || document.documentElement.clientWidth
      if (windowWidth < 768) {
        this.showRightToc = false
      }
    },
    isOnScreen (element) {
      const ON_SCREEN_HEIGHT = 50
      const ON_SCREEN_WIDTH = 50

      const rect = element.getBoundingClientRect()
      const windowHeight = window.innerHeight || document.documentElement.clientHeight
      const windowWidth = window.innerWidth || document.documentElement.clientWidth

      const elementHeight = element.offsetHeight
      const elementWidth = element.offsetWidth

      const onScreenHeight = ON_SCREEN_HEIGHT > elementHeight ? elementHeight : ON_SCREEN_HEIGHT
      const onScreenWidth = ON_SCREEN_WIDTH > elementWidth ? elementWidth : ON_SCREEN_WIDTH

      // 元素在屏幕上方
      const elementBottomToWindowTop = rect.top + elementHeight
      const bottomBoundingOnScreen = elementBottomToWindowTop >= onScreenHeight

      // 元素在屏幕下方
      const elementTopToWindowBottom = windowHeight - (rect.bottom - elementHeight)
      const topBoundingOnScreen = elementTopToWindowBottom >= onScreenHeight

      // 元素在屏幕左侧
      const elementRightToWindowLeft = rect.left + elementWidth
      const rightBoundingOnScreen = elementRightToWindowLeft >= onScreenWidth

      // 元素在屏幕右侧
      const elementLeftToWindowRight = windowWidth - (rect.right - elementWidth)
      const leftBoundingOnScreen = elementLeftToWindowRight >= onScreenWidth

      return bottomBoundingOnScreen && topBoundingOnScreen && rightBoundingOnScreen && leftBoundingOnScreen
    }
  },
  head () {
    return {
      title: `${this.Articels.post_title} - 轶哥小站`
    }
  }
}
</script>

<style lang="stylus" socped>
.articleDetails
  margin-top 30px
  background-color #fff
  padding 50px 10px

  .articleTitle
    text-align center
    font-size 24px

  .articalMeta
    text-align center
    padding 20px 0
    font-size 12px
    color #a1887f

    ul
      list-style none
      padding-right 20px

      > li
        display inline-block
        margin-left 20px
        line-height 2

        > i
          margin-right 8px

        > span a
          color #a1887f
          margin-left 10px

        a span
          color #a1887f

        > span a:first-child
          margin-left 0

      > li :first-child
        margin-left 0

  .articelContent
    margin-top 20px
    margin-bottom 30px
    line-height 2
    font-weight 300
    font-size responsive

    pre
      text-align 0.16rem
      overflow-x auto
      line-height 1

      code
        padding 16px

    code
      color #24292e
      background-color rgba(27, 31, 35, 0.05)
      border-radius 3px
      font-size 85%
      padding 2px 5px

.comment
  width 100%

.btnFooter
  font-size 12px
  margin-top 25px

  i
    margin 10px

.btnPrevt
  float left

.btnNext
  float right

footer .footer
  color #cccccc
  text-align left
  line-height 1.5
  margin 20px 0

.anchor-fix
  display block
  height 70px /* same height as header */
  margin-top -70px /* same height as header */
  visibility hidden

.articelRightToc
  position fixed
  width 15%
  top 0
  right 0
  overflow-y auto
  background-color #000
  padding 10px
  box-shadow 0 0 8px #000

.articelToc
  width 100%

.articelToc, .articelRightToc
  color #bbb
  user-select none

  .articelTitle
    font-weight 400
    margin-bottom 10px

  .articelTocList
    color #bbb

    a
      color #bbb

      &:visited
        color #bbb

      &:hover
        color #d01c2e

    ol.toc, ol.toc ol
      counter-reset toc
      list-style none

    ol li
      counter-increment toc

    .toc li:before
      content counters(toc, '.') ' '

    ol
      margin-left 20px

      li
        font-weight 400

        ol
          margin-left 20px

          li
            font-weight 300

@media (max-width: 768px)
  .articleDetails
    padding 20px
    margin-top 50px

  .articelRightToc
    position fixed
    width 80%
    top 100px
    bottom 95px
    right 10px
    background-color #000
    padding 10px
    overflow-y auto
    box-shadow 0 0 8px #000

  .mobileToc
    bottom 48px
</style>
