巴哈姆特文章列表強化

強化哈拉版的文章列表

目前为 2018-04-14 提交的版本。查看 最新版本

// ==UserScript==
// @name         巴哈姆特文章列表強化
// @namespace    https://blog.maple3142.net/
// @version      0.2
// @description  強化哈拉版的文章列表
// @author       maple3142
// @require      https://unpkg.com/[email protected]/dist/vue.min.js
// @require      https://unpkg.com/[email protected]/dist/vuejs-storage.min.js
// @match        https://forum.gamer.com.tw/B.php?*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function($,egg) {
    'use strict'
    const query=Object.assign(...location.search.replace(/^\?/,'').split('&').map(x=>x.split('=')).map(x=>({[x[0]]:x[1]})))
    const stringify=o=>'?'+Object.keys(o).map(k=>`${k}=${o[k]}`).join('&')

    // INFINITE LIST
    let firstpage=Math.max(query.page?parseInt(query.page):1,1)
    let lastpage=firstpage
    const $firstrow=$('<tr>').addClass('b-list__row')
    const $lastrow=$('<tr>').addClass('b-list__row')
    $('.b-list>tbody').append($lastrow)
    $('.b-list__head').after($firstrow)
    function xLoadFac(next){
        return $('<div>').css('text-align','center').css('padding','1rem').text('載入').click(e=>{
            if(!next&&firstpage===1){
                alert('已到首頁')
                return
            }
            if(next)lastpage++
            else firstpage--
            const q=location.pathname+stringify(Object.assign({},query,{page: next?lastpage:firstpage}))
            history.pushState(null,'',q)
            fetch(q)
                .then(r=>r.text())
                .then(h=>{

                // POST LIST
                const x=$(h).find('.b-list>tbody>.b-list__row')
                x.map((i,e)=>{
                    const a=$(e).find('.b-list__summary__sort a[data-subbsn]:last')
                    if(a.length){
                        a.text(subtitle(a.data('subbsn')))
                    }
                })
                if(next)$lastrow.before(x)
                else $firstrow.after(x)
                render() //rerender

                // PAGER
                const $oldpager=$('.b-pager')
                const $newpager=$(h).find('.b-pager')
                ;[0,1].forEach(x=>$oldpager.eq(x).replaceWith($newpager.eq(x)))
            })
        })
    }
    $('.b-list').before(xLoadFac(false)).after(xLoadFac(true))
    // UI
    $('.b-list__filter').append(`
<div id="x_filter">
<btn-cb class="btn-cb" v-model="filter.hidelock">隱藏鎖文</btn-cb>
<btn-cb class="btn-cb" v-model="filter.hidetop">隱藏置頂</btn-cb>
<btn-cb class="btn-cb" v-model="filter.hideimg">隱藏有圖片的文章</btn-cb>
</div>
`)
    Vue.use(vuejsStorage)
    Vue.component('btn-cb',{
        template: `<button :class="{active: value}" @click.prevent="$emit('input',!value)"><slot/></button>`,
        props: ['value']
    })
    const vm=new Vue({
        el: '#x_filter',
        data: {
            filter: {
                hidelock: false,
                hidetop: false,
                hideimg: false
            }
        },
        storage: {
            namespace: 'x_filter',
            keys: ['filter'],
            storage:{
                setItem: GM_setValue,
                getItem: GM_getValue
            }
        }
    })

    // RENDERING
    const isLocked=el=>$(el).find('.icon-lock').length>0
    const isTop=el=>$(el).hasClass('b-list__row--sticky')
    const isImg=el=>$(el).find('.icon-photo').length>0
    function render(){
        $('.b-list>tbody>.b-list__row').each((i,el)=>{
            if(vm.filter.hidelock && isLocked(el)){
                $(el).hide()
            }
            else if(vm.filter.hidetop && isTop(el)){
                $(el).hide()
            }
            else if(vm.filter.hideimg && isImg(el)){
                $(el).hide()
            }
            else{
                $(el).show()
            }
        })
    }
    vm.$watch('filter',{handler:render,deep:true})
    render()

    // CSS
    const css=document.createElement('style')
    css.textContent=`
#x_filter{
display: inline-block;
}
.btn-cb{
display: inline-block;
border: 0;
border-radius: 3px;
padding: 3px 12px;
height: 25px;
background-color: #117e96;
color: #FFF;
font-size: 12px;
margin-left: 5px;
}
.btn-cb.active{
background-color: #222e96;
}
`
    document.body.appendChild(css)
})(jQuery,$)