<template lang="pug">
.postPage
  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 && relationships.term_taxonomy.term && relationships.term_taxonomy.taxonomy === "category"', :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', v-viewer)
    .tools
      .reward(@click="reward") 打赏
    .comment(id="comment")
      .comment-title 交流区
        span(v-if="comments.length") ({{ commentAmount }})
      .comment-item(v-for="(item, index) in comments", :id="'comment_ID_' + item.comment_ID", :key="index")
        .comment-avatar
          img(:src="item.comment_author_avatar_url ? item.comment_author_avatar_url : 'https://picsum.photos/100/100/?blur=' + item.user_id")
        .comment-area
          .comment-author {{ item.comment_author }}
            span(class="comment-status", v-if="item.comment_approved === '0'") &nbsp; 此内容正在审核中...
          .comment-content(v-html="item.comment_content_html", v-viewer)
          .comment-info {{ item.comment_date }}
            span.reply(@click="reply(item.comment_ID, null, true)" v-if="replyLastID === null && item.comment_ID === replyID") 取消回复
            span.reply(@click="reply(item.comment_ID, null)" v-else) 回复
            span.reply(@click="check(item.comment_ID)" v-if="item.comment_approved === '0' && visitorInfo.manage") 通过审核
            span.reply(@click="check(item.comment_ID, 2)" v-else-if="visitorInfo.manage") 设为垃圾评论
        .comment-item(v-for="(i, inx) in item.children", :id="'comment_ID_' + i.comment_ID", :key="inx", style="margin-top: 15px; margin-left: 50px; background-color: #eeeeee; border-radius: 4px;")
          .comment-avatar
            img(:src="i.comment_author_avatar_url ? i.comment_author_avatar_url : 'https://picsum.photos/100/100/?blur=' + i.user_id")
          .comment-area
            .comment-author {{ i.comment_author }}
              span(class="comment-status", v-if="i.comment_approved === '0'") &nbsp; 此内容正在审核中...
            .comment-content(v-html="i.comment_content_html")
            .comment-info {{ i.comment_date }}
              span.reply(@click="reply(item.comment_ID, i.comment_ID)" v-if="replyLastID !== i.comment_ID") 回复
              span.reply(@click="reply(item.comment_ID, i.comment_ID, true)" v-else) 取消回复
              span.reply(@click="check(i.comment_ID)" v-if="i.comment_approved === '0' && visitorInfo.manage") 通过审核
              span.reply(@click="check(i.comment_ID, 2)" v-else-if="visitorInfo.manage") 设为垃圾评论
      p(v-if="!comments.length", style="color: #cecece; text-align: center; margin-top: 40px") 暂无内容
      .comment-default-commit
        .login(v-if="!visitorToken", @click="login")
          img(src="https://cdn.wyr.me/imgs/GitHub-Login.png")
        #editor
        .comment-toolbar
          .comment-no-userinfo(v-if="!visitorToken") 尚未登陆
          .comment-userinfo(v-else)
            .comment-avatar
              img(:src="visitorInfo.avatarURL")
            .comment-nickname {{ visitorInfo.nickname ? visitorInfo.nickname : (visitorInfo.username || '匿名') }}
            .comment-logout(@click="commentLogout") 退出
          .comment-btn(@click="commentCommit('editor')") 发布
      .comment-reply-commit(id="comment-reply-commit", v-show="replyID")
        .login(v-show="!visitorToken", @click="login")
          img(src="https://cdn.wyr.me/imgs/GitHub-Login.png")
        #editor-reply
        .comment-toolbar
          .comment-no-userinfo(v-if="!visitorToken") 尚未登陆
          .comment-userinfo(v-else)
            .comment-avatar
              img(:src="visitorInfo.avatarURL")
            .comment-nickname {{ visitorInfo.nickname ? visitorInfo.nickname : (visitorInfo.username || '匿名') }}
            .comment-logout(@click="commentLogout") 退出
          .comment-btn(@click="commentCommit('editor-reply')") 发布
    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")
  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']")
</template>

<script>
import remark from 'remark'
import strip from 'strip-markdown'

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
    }

    const truncated = (str, num) => {
      return Array.from(str).slice(0, num).join('')
    }

    const removeMarkdownFormat = (str) => {
      return new Promise((resolve, reject) => {
        remark()
          .use(strip)
          .process(str, function (err, file) {
            if (err) {
              reject(err)
              return
            }
            resolve(String(file))
          })
      })
    }

    // 获取评论
    const tmp = await $axios.$get(`/public/comments/post?ID=${route.params.id}`)
    const comments = tmp.result.list || []
    const commentAmount = tmp.result.amount || 0
    const markdownToText = await removeMarkdownFormat(result.post_excerpt)
    const description = truncated(markdownToText.replace(/[\r\n]/g, '').replace(/\s+/g, '').trim(), 200)

    return {
      postID: route.params.id,
      articels: result,
      description,
      comments,
      commentsMap: new Map(),
      commentAmount,
      showRightToc: false,
      tocIds: result.post_toc_ids,
      replyLastID: null,
      replyID: null,
      visitorToken: null,
      visitorInfo: {
        nickname: null,
        avatarURL: null,
        email: null,
        blog: null
      }
    }
  },
  mounted () {
    // 创建编辑器
    if (process.client) {
      this.visitorToken = window.localStorage.visitorToken
      if (this.visitorToken && window.localStorage.visitorInfo) {
        try {
          this.visitorInfo = JSON.parse(window.localStorage.visitorInfo)
          this.getCommentWithVisitorInfo(this.postID)
        } catch (_) { }
      }

      window.setAuthToken = (visitorToken, visitorInfo) => {
        window.localStorage.visitorToken = visitorToken
        window.localStorage.visitorInfo = JSON.stringify(visitorInfo)
        this.visitorToken = visitorToken
        this.visitorInfo = visitorInfo
        window.editorObj.vditor.options.upload.headers = {
          Authorization: 'Bearer ' + this.visitorToken
        }
        window.editorReplyObj.vditor.options.upload.headers = {
          Authorization: 'Bearer ' + this.visitorToken
        }
      }
      if (!window.editorObj && window.Vditor) {
        this.initEditor()
      }

      this.setCommentMap()
    }

    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
      }
    }

    if (this.$route.query.hash) {
      this.$nextTick(() => {
        setTimeout(() => {
          window.location.hash = '#' + this.$route.query.hash
          console.log('#' + this.$route.query.hash)
        }, 50)
      })
    }

    try {
      (adsbygoogle = window.adsbygoogle || []).push({}) // eslint-disable-line
    } catch (_) { }
  },
  methods: {
    initEditor () {
      const upload = {
        accept: 'image/*, video/*, audio/*, text/*, application/*, .rar, .zip, .php, .pptx, .ppt, .doc, .docx, .txt, .xls, .xlsx',
        url: process.env.baseURL + '/visitor/file/upload',
        max: 10485760, // 10 MB
        linkToImgUrl: process.env.baseURL + '/visitor/file/fetch',
        headers: {
          Authorization: 'Bearer ' + this.visitorToken
        },
        filename: name => encodeURIComponent(name.replace(/[^(a-zA-Z0-9\u4E00-\u9FA5\.)]/g, '') // eslint-disable-line
          .replace(/[\?\\/:|<>\*\[\]\(\)\$%\{\}@~]/g, '') // eslint-disable-line
          .replace('/\\s/g', '')),
        format (files, responseText) {
          return responseText
        },
        error: (_) => {
          this.$modal.show('dialog', {
            title: '提示',
            text: '上传失败，请检查网络稍后重试。<br>允许上传的文件类型：图片、视频、压缩文件、文本文件、Office文件、各类代码文件。'
          })
        }
      }

      window.editorObj = new window.Vditor('editor', {
        toolbar: [
          'emoji',
          'headings',
          'bold',
          'italic',
          'strike',
          'link',
          'list',
          'ordered-list',
          'outdent',
          'indent',
          'quote',
          'line',
          'code',
          'inline-code',
          'upload',
          'table',
          'insert-before',
          'insert-after',
          'undo',
          'redo',
          'fullscreen',
          {
            name: 'more',
            toolbar: [
              'edit-mode',
              'check',
              'both',
              'code-theme',
              'content-theme',
              'export',
              'outline',
              'preview',
              'devtools'
            ]
          }],
        minHeight: 250,
        toolbarConfig: {
          pin: true
        },
        cache: {
          enable: true
        },
        upload,
        placeholder: '我们书写的不是代码，而是人生'
      })

      window.editorReplyObj = new window.Vditor('editor-reply', {
        toolbar: [
          'emoji',
          'headings',
          'bold',
          'italic',
          'strike',
          'link',
          'list',
          'ordered-list',
          'outdent',
          'indent',
          'quote',
          'line',
          'code',
          'inline-code',
          'upload',
          'insert-before',
          'insert-after',
          'undo',
          'redo',
          {
            name: 'more',
            toolbar: [
              'table',
              'fullscreen',
              'edit-mode',
              'check',
              'both',
              'code-theme',
              'content-theme',
              'export',
              'outline',
              'preview',
              'devtools'
            ]
          }],
        minHeight: 220,
        toolbarConfig: {
          pin: true
        },
        cache: {
          enable: false
        },
        upload,
        placeholder: '我们书写的不是代码，而是人生'
      })
    },
    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
    },
    reward () {
      this.$modal.show('dialog', {
        title: '感谢支持',
        text: '<img src="https://cdn.wyr.me/imgs/reward.jpg" style="max-width: 100%; width: 400px"/>'
      })
    },
    reply (id, replyLastID, cancel) {
      const editorReplyObject = document.getElementById('comment-reply-commit')
      if (cancel) {
        this.replyID = null
        this.replyLastID = null
        window.location.hash = '_'
      } else {
        this.replyID = id
        this.replyLastID = replyLastID
        document.getElementById('comment_ID_' + id).appendChild(editorReplyObject)
        const comment = this.commentsMap.get(replyLastID)
        window.editorReplyObj.setValue('', true)
        this.$nextTick(() => {
          window.editorReplyObj.focus()
          if (replyLastID !== null) {
            window.editorReplyObj.insertValue('> ' + comment.comment_content + '  \n\n\n', true)
          } else {
            window.editorReplyObj.insertValue('', true)
          }
          window.location.hash = '#comment_ID_' + id
        })
      }
    },
    async commentCommit (type) {
      const parentID = this.replyID || 0
      const lastID = this.replyLastID || 0
      const postID = this.postID
      if (!postID) {
        alert('致命错误')
        return
      }

      const editorObj = type === 'editor-reply' ? window.editorReplyObj : window.editorObj
      const content = editorObj.getValue()

      if (!content || content === '\n') {
        this.$toasted.show('请输入内容', {
          position: 'top-center',
          duration: 5000
        })
        return
      }

      const { data } = await this.$axios({
        method: 'post',
        url: process.env.baseURL + '/comments/commit',
        headers: {
          Authorization: 'Bearer ' + this.visitorToken
        },
        data: {
          postID,
          lastID,
          parentID,
          content
        }
      })

      if (data.status === 1) {
        this.replyID = null
        this.replyLastID = null
        window.location.hash = '_'
        this.getCommentWithVisitorInfo(postID)
        editorObj.setValue('', true)
        this.$nextTick(() => {
          editorObj.focus()
          editorObj.insertValue('', true)
        })
      }
    },
    async check (ID, type) {
      const { data } = await this.$axios({
        method: 'post',
        url: process.env.baseURL + '/comments/check',
        headers: {
          Authorization: 'Bearer ' + this.visitorToken
        },
        data: {
          ID,
          type
        }
      })

      if (data.status === 1) {
        this.getCommentWithVisitorInfo(this.postID)
        this.$toasted.show(type === 2 ? '已删除' : '已通过', {
          position: 'top-center',
          duration: 5000
        })
      }
    },
    async getCommentWithVisitorInfo (postID) {
      // 获取评论
      const tmp = await this.$axios({
        method: 'get',
        url: process.env.baseURL + `/public/comments/post?ID=${postID}`,
        headers: {
          Authorization: 'Bearer ' + this.visitorToken
        }
      })
      const comments = tmp.data.result.list || []
      const commentAmount = tmp.data.result.amount || 0
      this.comments = comments
      this.commentAmount = commentAmount
      this.setCommentMap()
    },
    commentLogout () {
      window.localStorage.removeItem('visitorToken')
      this.visitorToken = null
    },
    login () {
      window.open('https://github.com/login/oauth/authorize?client_id=ce1673a37333e47e482d&redirect_uri=https://www.wyr.me/auth', 'Github授权', 'scrollbars=yes,resizable=yes,status=no,location=yes,toolbar=no,menubar=no,width=800,height=600,left=0,top=0')
    },
    setCommentMap () {
      const comments = this.comments
      for (let i = 0; i < comments.length; i++) {
        this.commentsMap.set(comments[i].comment_ID, comments[i])
        if (comments[i].children) {
          for (let j = 0; j < comments[i].children.length; j++) {
            this.commentsMap.set(comments[i].children[j].comment_ID, comments[i].children[j])
          }
        }
      }
    }
  },
  head () {
    const keywords = []
    for (let i = 0; i < this.articels.term_relationships.length; i++) {
      if (this.articels.term_relationships[i].term_taxonomy && this.articels.term_relationships[i].term_taxonomy.term && this.articels.term_relationships[i].term_taxonomy.taxonomy === 'post_tag') {
        keywords.push(this.articels.term_relationships[i].term_taxonomy.term.name)
      }
    }

    return {
      title: `${this.articels.post_title} - 轶哥`,
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: this.description
        },
        {
          hid: 'keywords',
          name: 'keywords',
          content: keywords.join(',')
        }
      ]
    }
  }
}
</script>

<style lang="stylus">
.postPage
  .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%
    margin-top 60px

    .comment-title
      color #777
      margin-bottom 30px

    .comment-item
      margin-top 10px
      padding 10px 8px

      .comment-avatar
        float left
        margin-top 3px

        img
          border-radius 50%
          width 40px
          border-style none
          cursor pointer
          box-sizing border-box
          margin 0

      .comment-area
        margin-left 50px

        .comment-author, .comment-info
          font-size 10px

        .comment-author
          color #a1887f

        .comment-info
          color #777

          .reply
            color #a1887f
            cursor pointer
            user-select none
            margin-left 10px

    .comment-no-userinfo
      float left
      font-size 12px
      line-height 50px
      margin-left 10px

    .comment-userinfo
      width 200px
      position relative
      cursor pointer
      user-select none
      margin-top 10px
      margin-left 10px
      display inline-block
      height 30px

      .comment-avatar
        position absolute
        left 0
        top 0
        width 30px
        height 30px
        overflow hidden

        img
          border-radius 50%
          width 30px
          height 30px
          border-style none
          box-sizing border-box
          margin 0

      .comment-nickname
        color #a1887f
        margin-left 50px
        height 30px
        line-height 30px
        font-size 12px
        width 150px
        overflow hidden
        text-overflow ellipsis
        white-space nowrap

    .comment-content
      width 100%
      padding 5px 0

      img
        max-width 100%

    .comment-status
      color #ca7474

    .comment-logout
      width 51px
      height 100%
      line-height 30px
      border 1px solid #586069
      font-size 12px
      border-radius 2px
      box-sizing border-box
      display none
      text-align center

    .comment-userinfo:hover
      .comment-avatar, .comment-nickname
        display none

      .comment-logout
        display block

    .comment-userinfo:active
      .comment-logout
        background-color #586069
        color #fff

    #editor
      margin-top 10px
      border-bottom-color #e6e5e5
      border-bottom-style dotted
      border-bottom-left-radius 0
      border-bottom-right-radius 0

    .comment-toolbar
      width 100%
      height 50px
      flex-direction column
      border 1px solid #d1d5da
      border-radius 3px
      box-sizing border-box
      border-top none
      border-top-left-radius 0
      border-top-right-radius 0
      color #586069

    .comment-btn
      color #586069
      float right
      line-height 12px
      margin-top 12px
      margin-right 10px
      padding 6px 12px
      border 1px solid #586069
      box-sizing border-box
      font-size 12px
      cursor pointer
      user-select none
      border-radius 2px

    .comment-btn:active
      background-color #586069
      color #fff

    .comment-reply-commit
      margin 10px 0 10px 50px

    .comment-default-commit
      margin-top 125px

    .comment-default-commit, .comment-reply-commit
      position relative

      .login
        position absolute
        left 0
        top 0
        width 100%
        height 100%
        text-align center
        line-height 1
        margin auto
        z-index 99
        cursor pointer
        user-select none

        img
          margin-top 70px

      .login:hover
        background-color #fff

      .login:before
        content ''
        position absolute
        background rgba(0, 0, 0, 0.1)
        top 0
        left 0
        width 100%
        height 100%
        filter blur(5px)
        z-index 9

  #editor-reply
    margin 0

  .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
    font-size 12px
    position fixed
    width 15%
    top 0
    right 0
    overflow-y auto
    background-color #000
    padding 10px
    box-shadow 0 0 8px #000
    z-index 999
    padding-bottom 20px
    min-width 240px
    max-width 300px

  .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
        margin-top 6px

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

      ol
        margin-left 20px

        li
          font-weight 400

          ol
            margin-left 20px

            li
              font-weight 300

  .tools
    margin-top 80px
    margin-bottom 10px
    text-align center
    user-select none

    .reward
      margin 15px 0
      border 1px solid #888
      padding 5px 10px
      display inline-block
      color #888
      font-weight 300
      cursor pointer
      margin auto

  .vditor--fullscreen
    z-index 9999

@media (max-width: 768px)
  .postPage
    .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>
