// ==UserScript== // @name bilibili网页端添加APP首页推荐 // @namespace indefined // @version 0.6.0 // @description 网页端首页添加APP首页推荐、全站排行、可选提交不喜欢的视频 // @author indefined // @supportURL https://github.com/indefined/UserScripts/issues // @match *://www.bilibili.com/* // @license MIT // @connect app.bilibili.com // @connect api.bilibili.com // @connect passport.bilibili.com // @connect link.acg.tv // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @run-at document-idle // @downloadURL none // ==/UserScript== (function() { 'use strict'; const style = ``; //APP首页推荐 function InitRecommend () { //初始化标题栏并注入推荐下方 element.mainDiv.id = 'recommend'; let scrollBox; if(element.isNew){ element._s(element.mainDiv.querySelector('.storey-title'),{ innerHTML:style, childs:[ '
猜你喜欢
', { nodeType:'div', className:'exchange-btn', childs:[ { nodeType:'div', className:'btn btn-change', innerHTML:'更多', onclick:getRecommend }, { nodeType:'span', className:'btn more', innerHTML:'设置', onclick:()=>setting.show() } ] } ] }); scrollBox = element.mainDiv.querySelector('div.zone-list-box'); scrollBox.classList.add('storey-box') } else { element._s(element.mainDiv.querySelector('div.zone-title'),{ innerHTML:style, childs:[ { nodeType:'div', className:'headline clearfix', innerHTML:'猜你喜欢', childs:[ { nodeType:'div', className:'link-more',style:'cursor:pointer;user-select: none;', innerHTML:'设置 ', onclick:()=>setting.show() }, { nodeType:'div', className:'read-push',style:'cursor:pointer;user-select: none;', innerHTML:'加载更多', onclick:getRecommend } ] } ] }); scrollBox = element.mainDiv.querySelector('div.storey-box.clearfix'); } let listBox; element._s(scrollBox,{ innerHTML:'',style:'overflow:hidden auto;display:block', childs:[listBox = element._c({ nodeType:'div',className:scrollBox.className, id:'recommend-list',style:'overflow-y: auto;align-content: flex-start;', innerHTML:'empty' })] }); const moreButton = element._c({ nodeType:'div',className:"clearfix", innerHTML:'
回到推荐顶部
', onclick:()=>{ listBox.scrollTop = 0; scrollBox.scrollTop = 0; element.mainDiv.scrollIntoView(); } }); scrollBox.insertAdjacentElement('afterend',moreButton); if(element.isNew) { document.querySelector('.proxy-box').insertAdjacentElement('afterbegin',element.mainDiv); } else { document.querySelector('#home_popularize').insertAdjacentElement('afterend',element.mainDiv); } const recommends = [];//保存当前页面中的推荐元素,用于清除多余内容 //显示历史推荐 if(setting.historyData) updateRecommend(setting.historyData); //加载新推荐 for(let i=0;i{ try { const rep = JSON.parse(res.response); if (rep.code!=0){ loadingDiv.firstChild.innerText = `请求app首页失败 code ${rep.code}
msg ${rep.message}`; return console.error('请求app首页失败',rep); } setting.pushHistory(rep.data); updateRecommend(rep.data); loadingDiv.style.display = 'none'; } catch (e){ loadingDiv.firstChild.innerText = `请求app首页发生错误 ${e}`; console.error(e,'请求app首页发生错误'); } }, onerror: e=>{ loadingDiv.firstChild.innerText = `请求app首页发生错误 ${e}`; console.error(e,'请求app首页发生错误'); } }); } //旧版创建视频卡 function createOldRecommend(data) { return element._c({ nodeType:'div', className:'spread-module', childs:[{ nodeType:'a',target:'_blank', href:data.goto=='av'?`/video/av${data.param}`:data.uri, dataset:{ tag_id:data.tag?data.tag.tag_id:'', id:data.param,goto:data.goto,mid:data.mid,rid:data.tid }, childs:[ { nodeType:'div',className:'pic', childs:[ `
${data.title}
`, `${data.tname||data.badge}`, data.duration&&`${tools.formatNumber(data.duration,'time')}`||'', data.goto=='av'?{ nodeType:'div', dataset:{aid:data.param},title:'稍后再看', className:'watch-later-trigger w-later', onclick:tools.watchLater }:'', (data.dislike_reasons&&setting.accessKey)?{ nodeType:'div',innerText:'X', className:'dislike-botton', childs:[{ nodeType:'div', className:'dislike-list', childs:data.dislike_reasons.map(reason=>({ nodeType:'div', dataset:{reason_id:reason.reason_id}, innerText:reason.reason_name, title:`提交因为【${reason.reason_name}】不喜欢`, onclick:dislike, })) }] }:'' ] }, `

${data.title}

`, `

${tools.formatNumber(data.play)}` +`${tools.formatNumber(data.danmaku)}` ] }] }) } //新版创建视频卡 function createNewRecommend(data) { return element._c({ nodeType:'div',style:'display:block', className:'video-card-common', childs:[ { nodeType:'div',className:'card-pic', dataset:{ tag_id:data.tag?data.tag.tag_id:'', id:data.param,goto:data.goto,mid:data.mid,rid:data.tid }, childs:[ `` + `${data.title}

` + `
${tools.formatNumber(data.play)}` +(data.like&&`${data.like}
`||'
') + `
${data.duration&&tools.formatNumber(data.duration,'time')||''}
`, `${data.tname||data.badge}`, data.goto=='av'?{ nodeType:'div', dataset:{aid:data.param},title:'稍后再看', className:'watch-later-video van-watchlater black', onclick:tools.watchLater }:'', (data.dislike_reasons&&setting.accessKey)?{ nodeType:'div',innerText:'X', className:'dislike-botton', childs:[{ nodeType:'div', className:'dislike-list', childs:data.dislike_reasons.map(reason=>({ nodeType:'div', dataset:{reason_id:reason.reason_id}, innerText:reason.reason_name, title:`提交因为【${reason.reason_name}】不喜欢`, onclick:dislike, })) }] }:'' ] }, `${data.title}`, `${data.name||data.badge}`, ] }) } //显示推荐视频 function updateRecommend (datas){ const point = listBox.firstChild; datas.forEach(data=>{ const recommend = element.isNew?createNewRecommend(data):createOldRecommend(data); recommends.push(point.insertAdjacentElement('beforeBegin',recommend)); }); //移除多余的显示内容 while(setting.pageLimit && recommends.length>setting.pageLimit) listBox.removeChild(recommends.shift()); listBox.scrollTop = 0; scrollBox.scrollTop = 0; } //提交不喜欢视频,视频数据提前绑定在页面元素上 function dislike (ev) { let target=ev.target,parent=target.parentNode; let cancel; let url = `https://app.bilibili.com/x/feed/dislike`; if (parent.className!='dislike-list'){ cancel = true; let deep = 1; while(!parent.dataset.id&&deep++<4){ target = parent; parent=target.parentNode; } if (!parent.dataset.id){ tools.toast('请求撤销稍后再看失败:页面元素异常',ev); return false; } url += `/cancel`; }else{ parent = parent.parentNode.parentNode; if(!element.isNew) parent = parent.parentNode; } url += `?goto=${parent.dataset.goto}&id=${parent.dataset.id}&mid=${parent.dataset.mid}` +`&reason_id=${target.dataset.reason_id}&rid=${parent.dataset.rid}&tag_id=${parent.dataset.tag_id}`; if (setting.accessKey) url += '&access_key='+ setting.accessKey; const handleCover = ()=>{ if (cancel){ parent.removeChild(target); }else{ const cover = document.createElement('div'); cover.className = 'dislike-cover'; cover.dataset.reason_id = target.dataset.reason_id; cover.innerHTML = `

提交成功,但愿服务器以后少给点这种东西。

点击撤销操作
`; cover.onclick = dislike; parent.appendChild(cover); } }; //console.log(url); GM_xmlhttpRequest({ method: 'GET',url, onload: res=>{ try { const par = JSON.parse(res.response); if (par.code == 0){ handleCover(); }else if((par.code==-101 && par.message=='账号未登录') || par.code==-400){ setting.storageAccessKey(undefined); tools.toast(`未获取授权或者授权失效,请点击设置重新获取授权`); } else{ tools.toast(`请求不喜欢错误 code ${par.code}
msg ${par.message}`,{par,url}); } } catch (e){ tools.toast(`请求不喜欢发生错错误${e}`,e); } }, onerror: e=>{ tools.toast(`请求不喜欢发生错误`,e); } }); return false; } } //全站排行榜 function InitRanking(){ let rankingAll; if(element.isNew) { //……直接把旧版的排行修一修搬过来用吧 rankingAll = element.mainDiv.querySelector('.rank-list'); element._s(rankingAll,{ className:'sec-rank report-wrap-module zone-rank rank-list', innerHTML:`

排行

全部
原创
三日
查看更多` }); } else { rankingAll = element.mainDiv.querySelector('#ranking_douga'); } rankingAll.id = 'ranking-all'; const rankingHead = rankingAll.querySelector('.rank-head'); rankingHead.firstChild.innerText = '全站排行'; const tab = rankingHead.querySelector('.bili-tab.rank-tab'); const dropDown = rankingHead.querySelector('.bili-dropdown.rank-dropdown'); const warp = rankingAll.querySelector('.rank-list-wrap'); let type = 1,day = setting.rankingDay; const data = {1:{},2:{}}; const loading = element.getLoadingDiv(); const detail = {}; dropDown.firstChild.innerText = setting.rankingDays[day]; element._s(dropDown.lastChild,{ innerHTML:'', childs:Object.entries(setting.rankingDays).map(([value,text])=>({ nodeType:'li',innerText:text, dataset:{day:value}, className:'dropdown-item' })) }); //创建一个显示详情的浮窗 detail.div = element._c({ nodeType:'div',style:'display:none', className:'video-info-module', onmouseenter: ()=> (detail.div.style.display = 'block'), onmouseleave: ()=> (detail.div.style.display = 'none'), childs:[ '