Merge branch 'simple-home' into preview

This commit is contained in:
the1812 2019-10-26 16:25:38 +08:00
commit e9f926e609
40 changed files with 1330 additions and 138 deletions

View File

@ -135,6 +135,7 @@ declare global {
cid: string | undefined
pageno: string | number | undefined
$: JQueryStatic
[key: string]: any
}
class SpinQuery {
static condition<T>(query: () => T, condition: (queryResult: T) => boolean, success: (queryResult: T) => void, failed?: () => void): void;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
min/blackboard.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(e,t)=>{const r=async()=>{if(dq(".international-home")){const e=await SpinQuery.condition(()=>unsafeWindow["__INITIAL_STATE__"],e=>e!==undefined);return dqa(".home-slide .item").map((t,r)=>{const i=t.querySelector("a").getAttribute("data-loc-id");return{url:e.locsData[i][r].url,title:t.querySelector(".title").innerText.trim(),isAd:Boolean(t.querySelector(".gg-icon")),imageUrl:t.querySelector("img").getAttribute("src").replace(/@.+$/,"")}})}else{const e=dq(".chief-recommend-module .panel");const t=e.querySelector(".pic");const r=e.querySelectorAll(".title > a");return[...t.querySelectorAll("li")].map((e,t)=>{const i=r[t];return{url:i.getAttribute("href"),title:i.innerText.trim(),isAd:Boolean(i.querySelector(".gg-pic")),imageUrl:e.querySelector("img").getAttribute("src").replace(/@.+$/,"")}})}};return{export:{getBlackboards:r}}}})();

1
min/blackboard.vue.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(a,r)=>{const i=`<div class=blackboards><div class=header><div class=title>活动</div><a class=more href=https://www.bilibili.com/blackboard/x/act_list/ target=_blank><icon type=mdi icon=dots-horizontal></icon>更多</a></div><input class="hidden-input blackboard-radio"type=radio name=blackboard v-for="(b, i) of blackboards":checked="i === 0":id="'blackboard' + i":data-index=i :key=i><div class=jump-dots><label v-for="(b, i) of blackboards":for="'blackboard' + i":key=i><div class=jump-dot></div></label></div><div class=blackboard-cards><a class=blackboard-card target=_blank v-for="(b, i) of blackboards":key=i :href=b.url :title=b.title><dpi-img :src=b.imageUrl :alt=b.title :size="{width: 500, height: 250}":root=cardsContainer></dpi-img><div class=title>{{b.title}}</div></a></div></div>`;r.applyStyleFromText(`.simple-home .blackboards{display:grid;grid-template-areas:"header header" "dots cards";grid-template-columns:8px 1fr;grid-template-rows:1fr 250px;row-gap:16px;column-gap:16px;align-self:start}.simple-home .blackboards .blackboard-cards{grid-area:cards;--blackboard-width:500px;--blackboard-height:250px;width:var(--blackboard-width);height:var(--blackboard-height);border-radius:16px;overflow:hidden}.simple-home .blackboards .blackboard-cards .blackboard-card{width:100%;height:100%;position:relative;display:block;transition:.3s cubic-bezier(.65,.05,.36,1)}.simple-home .blackboards .blackboard-cards .blackboard-card img{width:100%;height:100%;object-fit:fill;display:block}.simple-home .blackboards .blackboard-cards .blackboard-card .title{position:absolute;bottom:8px;left:50%;transform:translateX(-50%);padding:4px 16px;color:#fff;background-color:#000a;font-size:14px;font-weight:700;border-radius:14px;white-space:nowrap;opacity:0}.simple-home .blackboards .blackboard-cards .blackboard-card:hover .title{opacity:1}`,"blackboard-style");return{export:Object.assign({template:i},{components:{Icon:()=>r.importAsync("icon.vue"),"dpi-img":()=>r.importAsync("dpi-img.vue")},data(){return{blackboards:[],interval:0}},destroyed(){if(this.interval){clearInterval(this.interval)}},computed:{cardsContainer(){return this.$el.querySelector(".blackboard-cards")}},async mounted(){const{getBlackboards:a}=await r.importAsync("blackboard");this.blackboards=(await a()).filter(a=>!a.isAd);const i=dq(".blackboards");this.interval=setInterval(()=>{if(!document.hasFocus()||i.matches(".blackboards:hover")){return}const a=parseInt(dq(`.blackboard-radio:checked`).getAttribute("data-index"));let r;if(a===this.blackboards.length-1){r=0}else{r=a+1}dq(`.blackboard-radio[data-index='${r}']`).checked=true},5e3)}})}}})();

View File

@ -12,6 +12,8 @@
"auto-play.min.js": "DC9938AC15DADDC9D88DCA0C9BE64BE142C37D32CB85E42E23DAB2A7378531E5",
"batch-download.min.js": "A0F979F33A06E23D3800525CF70700170565EBD98579CE394ECE4CC66AAEEB5A",
"biliplus-redirect.min.js": "9882D14DAC5C103212A101A5168883C41B4B3B2737FD5F222DC343D0304FF8AF",
"blackboard.min.js": "83988755E158B557CB1AA80B526AE969CFB82AA00ACCB03F3A4B333DBD37B24B",
"blackboard.vue.min.js": "8F1984AB69B029701DC88F33568EF1881D0C54EEC72D65EA3029CF2F68BD6674",
"blur-video-control.min.css": "B72FA7AD198ED1C9A9620A83881441F96F9FF3083ED12203A324B9753A7CCFFD",
"blur-video-control.min.js": "00A2AC837FC455DF2AED7D0C350265C7438CC6F5C203F085E19639DDB86D0E11",
"clear-cache.min.js": "44EA6B2597B887B6FAC42A82E1CCE39A64494ABFC813AC984A90476ED10BA714",
@ -45,12 +47,12 @@
"download-video.min.css": "1183440AB062DD7C26E68440F4FE4187395E9CFBA671497C362282F0CFC6090A",
"download-video.min.html": "4311ABAF2886EB02B1003EA864DD605B113CDB05FF04C3A6882AD931F320D216",
"download-video.min.js": "3413706B68FF52C6BC592187D39BFC1046178AE62D56D41E533D30A4780BC49F",
"dpi-img.vue.min.js": "D4833A242EBDD84834B11DB4CEB68B8807BDFC9693C3E1AAE73071986FE26F78",
"dpi-img.vue.min.js": "3D9D93079365DCABA8DC8970F051AD1A7F25C3EFFF850CD1000C4312E9B910DD",
"expand-danmaku.min.js": "B21658C40085AEA8DC49652AE62EB8610BB2EBEAF7A9C9AF69EF3B11E08EEC8D",
"expand-description.min.css": "58C7710A50521B80F7D872BDC4C652610D84C4FABC6874BA66DA37B4F8759224",
"expand-description.min.js": "A56857AD6B1C9F431B233D188E857D30DD5A2EB644986DE32A21280B1B7BC7A7",
"favorites-redirect.min.js": "70D6ECCE0402AA76387D2A3288C1148C60CC88D5378B7A2BDC813F3F78E4EE84",
"feeds-apis.min.js": "2C704CF50C6F2C562AC2FCD7E6C9706E63E109D2FB4A6836BFE316C34D4A4FCE",
"feeds-apis.min.js": "C103FC41098D68EC6E5252E3A1AF570601D753AE7E65811E0899F00CD9B10588",
"feeds-filter-card.vue.min.js": "5922DD76080D5DD57C860018749BD3D82530DDBD537DBFB5D540D10C03645775",
"feeds-filter.min.js": "10557E498B8BADA3C1C03E8C1DCD6FB24DBA2DA27A5A03BD861054F7E2989D46",
"filter-type-switch.vue.min.js": "86F40D40C2464A56A2A0D32A0B94860DD376D1FE7850836B4CE37B767312BBE7",
@ -107,6 +109,7 @@
"notify-new-version.min.js": "B657B4A67D791FC413E1DBF2BBC59A79EE453582F44F17BF9157D927891BAE96",
"old-tweets.min.js": "387152B26384B0900985F527112841CC00A48F507EAA8FA634D13FFA83447A72",
"old.min.css": "4C8C918BEBE59E9EE19D5E383234767EE2A2F1DB72E86F0C9F9CE01F26DD193C",
"online-info-row.vue.min.js": "F2884079823918868F4DBC3EC6F8D416BCA320AE6988F2280C8AF1344B5F6BB2",
"outer-watchlater.min.css": "B40E94BADA1A9BC96422777B33150780330763098B539921DA05F9D3BA487424",
"outer-watchlater.min.js": "B6D702917A31B4028464CB9B89CB45EB1ABF38E6EE8E682CF8812546EE8194DC",
"override-navbar.min.css": "E5AA612841281169CA367A238FB934F807900A385CE2298B7352FF3CA4623757",
@ -133,10 +136,12 @@
"settings-tooltip.min.js": "E9ABA72B3C29CA850342109E57B055B193F3356DD59876B202E8E908AE6247C9",
"settings-tooltip.zh-CN.min.js": "AD93F86107EC6840A24BCFF7DE3DB87C620A7591D88CFD4A2E41C058B7ED5585",
"show-dead-video-title.min.js": "8D591930421EBA43A1BDF50DC8B645C1BD1A17E109FB1CFBCD6B78E6C74E1D68",
"simple-home.vue.min.js": "030C853AE068A918E540BCD491A40831F069BC88375230E40BB4B964E4252FB2",
"simplify-home.min.css": "C12B89218065EB887D4330C93747822115B31AD93073FF9F89AA585AEC9752CD",
"simple-home-categories.vue.min.js": "50A7633639E8ECFA05C8E020B537CDB6E8C5AA8C6046B3DD2DDD76F126504BF4",
"simple-home-feeds.vue.min.js": "EE124BFD22D450DA63E7B9DF8BB612DB5D62089F6CB912ACB87D0DF1BCBB099E",
"simple-home.vue.min.js": "F5E28EE015C0FE13651628749E3044AA3DF67E98C86603A527C04BC9917FAF9E",
"simplify-home.min.css": "50F0FA046D61ECE5183409CF97C8DBECB4CF64918DF813CD2B39BF9FBD314B42",
"simplify-home.min.js": "F6D7F8E0D45847C3E056711AECE3832785603E7EF85A4B995C028F5CBE539C94",
"simplify-home.vue.min.js": "073A24094C480D6DD79006C3704002563AD9DF1BA496FF937DFE4A25869722E8",
"simplify-home.vue.min.js": "62F246FD5C9172676A077DD1DFB1F5ACE0E018952D13E1AAD89B3EA2FD00F961",
"simplify-liveroom.min.css": "98F872E5BE28B4949302145A12ED047EF01C4E40A16176E5C39A6AFD540CCC41",
"simplify-liveroom.min.js": "16C7DFF5204E5A020371C5F050A9557C65C8B25283145FBC6BBD892E82016C35",
"skip-charge-list.min.css": "D3C988CE131CEBFAC8A60360529C83EC4AE1B9EA122F9A6924F19963E25A4FE9",
@ -154,14 +159,17 @@
"touch-navbar.min.js": "21EF203296CF795E2471D04E7C44F5FA734FC7EB3EF6187B5AC6D562572D2649",
"touch-player.min.css": "C1988B4756185611653E666C0C9E825C9B6AA36FA47D362CC2CD9390DC1E2281",
"touch-player.min.js": "5CA0C5A0621330ABBD62B31042ADDF9019D27DEA7D58B69CB959C90B25D8C8F5",
"trending-videos.min.js": "FB1507281A70FADBFC51B2BD5A94F765868F380673B5A1ECE19E4E333A383625",
"trending-videos.vue.min.js": "AB940B24961870F52DEC3142D04E506828A1D4CF427F0A6F8E998BBFBF5BB2D0",
"tweets.min.css": "9015C1F165C91B9205ABBE4E8A3B5FA83DB1EB4B5CF2442846AF61E44FF178A8",
"v-checkbox.vue.min.js": "A23C35D5627009A29FD396A024442A19E37DEE70674BF3CE0FA377D781ED2231",
"v-dropdown.vue.min.js": "66C883695F6653412980050A23F7581557407A2859214BF0CAAEC7001D0B5DDB",
"video-card.vue.min.js": "E6FE8542E8910ED47A8D677533D213934682318A71A071BEF2BD4DFB7E01F33E",
"video-card-info.min.js": "13B755C0EE0CA018AE65251E168BAF3395FEA2EB4FAD6949AADD752F61B8819B",
"video-card.vue.min.js": "340436CDE3B102F467F671411D4373E0DBF59C5A72867D18BDF45BA6C66156C2",
"video-dash.min.js": "9684C74C7782FA18DB45C262F8C41460ABB973C8B1868A5FBBD1DD2608E3C90D",
"video-downloader-fragment.min.js": "13B755C0EE0CA018AE65251E168BAF3395FEA2EB4FAD6949AADD752F61B8819B",
"video-info.min.js": "7234A74CA28A772A31E41BBD4925FC2B22C6701419ADFD511402C6A9D6D9E5FA",
"video-list.vue.min.js": "3949826DB0DB7A563F7F239F3DF0E51D048ADCAD06D91CC8E5C0EE8A8D4E10DE",
"video-list.vue.min.js": "BC1DB652C4CD8E98AC620E74ED306AACE0CD99359EE472BFD2A846ADCA37AD0B",
"video-story.min.js": "F9D4D2D80997DF5F11BF0CFA4D389B77BDBF1566EA6002E47174B68B440F3C0D",
"view-cover.min.js": "E4960587BFC4A219278EC300AFC8983AE4064D6FDBB42093E4EB7590726E229E",
"watchlater-api.min.js": "0A341429EFB4489594C6670A1FEEF99E7EC2564FF18BCE3A679E98101BA0F2F4",

Binary file not shown.

View File

@ -1 +1 @@
(()=>{return(t,e)=>{const i=`<img :width=width :height=height :srcset=srcset :src=src :style="{filter: blur ? 'blur(' + blur + 'px)' : undefined}">`;return{export:Object.assign({template:i},{props:["size","src","blur"],computed:{srcset(){if(!this.src||!this.size){return null}return getDpiSourceSet(this.src,this.size)},width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();
(()=>{return(t,s)=>{const e=`<img :width=width :height=height :srcset=srcset :src=actualSrc :style="{filter: blur ? 'blur(' + blur + 'px)' : undefined}">`;return{export:Object.assign({template:e},{props:["size","src","blur","root","rootMargin","threshold"],data(){return{srcset:null,actualSrc:null}},methods:{calcSrc(){if(!this.src||!this.size){return null}const t=this.src.substring(this.src.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(this.src,this.size,t);this.actualSrc=this.src}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const s=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();s.disconnect()}})},t);s.observe(this.$el)},computed:{width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();

View File

@ -1 +1 @@
(()=>{return(e,t)=>{const r={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class n extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,r){super.addEventListener(e,t,r)}removeEventListener(e,t,r){super.removeEventListener(e,t,r)}addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.forEach(e=>e.stop());this.addCard(e)}})}else{const t=this.parseCard(e);this.cards.push(t);const r=new CustomEvent("addCard",{detail:t});this.dispatchEvent(r)}}}removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=this.parseCard(e).id;const r=this.cards.findIndex(e=>e.id===t);const n=this.cards[r];this.cards.splice(r,1);const s=new CustomEvent("removeCard",{detail:n});this.dispatchEvent(s)}}parseCard(e){const t=t=>{if(e.querySelector(t)===null){return""}return e.querySelector(t).innerText};const n=e=>{const r=parseInt(t(e));if(isNaN(r)){return 0}return r};const s=(()=>{if(e.querySelector(".repost")){return r.repost}if(e.querySelector(".imagesbox")){return r.textWithImages}if(e.querySelector(".video-container")){return r.video}if(e.querySelector(".bangumi-container")){return r.bangumi}if(e.querySelector(".article-container")){return r.column}if(e.querySelector(".music-container")){return r.audio}if(e.querySelector(".h5share-container")){return r.share}if(e.querySelector(".vc-ctnr")){return r.miniVideo}return r.text})();const i={id:e.getAttribute("data-did"),username:t(".main-content .user-name"),text:t(".card-content .text.description"),reposts:n(".button-bar .single-button:nth-child(1) .text-offset"),comments:n(".button-bar .single-button:nth-child(2) .text-offset"),likes:n(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:s};e.setAttribute("data-type",s.id.toString());return i}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const s=new n;return{export:{feedsCardsManager:s,feedsCardTypes:r}}}})();
(()=>{return(e,t)=>{const r={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class n extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,r){super.addEventListener(e,t,r)}removeEventListener(e,t,r){super.removeEventListener(e,t,r)}addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.forEach(e=>e.stop());this.addCard(e)}})}else{const t=this.parseCard(e);this.cards.push(t);const r=new CustomEvent("addCard",{detail:t});this.dispatchEvent(r)}}}removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=this.parseCard(e).id;const r=this.cards.findIndex(e=>e.id===t);const n=this.cards[r];this.cards.splice(r,1);const i=new CustomEvent("removeCard",{detail:n});this.dispatchEvent(i)}}parseCard(e){const t=t=>{if(e.querySelector(t)===null){console.warn(e,t);return""}return e.querySelector(t).innerText};const n=e=>{const r=parseInt(t(e));if(isNaN(r)){return 0}return r};const i=(()=>{if(e.querySelector(".repost")){return r.repost}if(e.querySelector(".imagesbox")){return r.textWithImages}if(e.querySelector(".video-container")){return r.video}if(e.querySelector(".bangumi-container")){return r.bangumi}if(e.querySelector(".article-container")){return r.column}if(e.querySelector(".music-container")){return r.audio}if(e.querySelector(".h5share-container")){return r.share}if(e.querySelector(".vc-ctnr")){return r.miniVideo}return r.text})();const a={id:e.getAttribute("data-did"),username:t(".main-content .user-name"),text:t(".card-content .text.description"),reposts:n(".button-bar .single-button:nth-child(1) .text-offset"),comments:n(".button-bar .single-button:nth-child(2) .text-offset"),likes:n(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:i};e.setAttribute("data-type",i.id.toString());return a}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const i=new n;const a=async(e="video")=>{const r=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${e==="video"?8:512}`);if(r.code!==0){throw new Error(r.message)}if(e==="video"){const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const n=await e();return r.data.cards.map(e=>{const t=JSON.parse(e.card);const r=_.get(e,"display.topic_info.topic_details",[]).map(e=>{return{id:e.topic_id,name:e.topic_name}});return{id:e.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:e.desc.user_profile.info.uid,upName:e.desc.user_profile.info.uname,upFaceUrl:e.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:e.timestamp,time:new Date(e.timestamp*1e3),topics:r,dynamic:t.dynamic,like:formatCount(e.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:n.includes(t.aid)}})}else if(e==="bangumi"){return r.data.cards.map(e=>{const t=JSON.parse(e.card);return{id:e.desc.dynamic_id_str,aid:t.aid,epID:t.episode_id,title:t.new_desc,upName:t.apiSeasonInfo.title,upFaceUrl:t.apiSeasonInfo.cover,coverUrl:t.cover,description:"",timestamp:e.timestamp,time:new Date(e.timestamp*1e3),like:formatCount(e.desc.like),durationText:"",playCount:formatCount(t.play_count),danmakuCount:formatCount(t.bullet_count),watchlater:false}})}else{return[]}};return{export:{feedsCardsManager:i,feedsCardTypes:r,getVideoFeeds:a}}}})();

1
min/online-info-row.vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
min/simple-home-categories.vue.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(e,i)=>{const s=`<div class=categories><div class=header><div class=title>分区</div></div>快了, 已经在路上了.jpg</div>`;i.applyStyleFromText(`.simple-home .categories{display:flex;flex-direction:column}`,"simple-home-categories-style");return{export:Object.assign({template:s},{})}}})();

1
min/simple-home-feeds.vue.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(e,t)=>{const a=`<div class=feeds><div class=header><div class=tabs><div class=title>动态</div><div class=tab v-for="tab in tabs":key=tab.type @click=changeTab(tab) :class="{active: currentTab === tab}"><div class=tab-name>{{tab.name}}</div></div></div><a class=online target=_blank href=https://www.bilibili.com/video/online.html>在线人数: {{online}}</a><a class=more href=//t.bilibili.com/ target=_blank><icon type=home icon=activity></icon>全部动态</a></div><div class=contents><div class=card-wrapper v-for="card in feedCards":key=card.id><video-card :data=card orientation=vertical></video-card></div></div></div>`;t.applyStyleFromText(`.simple-home .feeds{justify-self:start;display:grid;grid-template-areas:"header header" "contents contents";grid-template-columns:repeat(2,auto);grid-template-rows:repeat(2,auto);row-gap:16px;column-gap:16px}.simple-home .feeds .header,.simple-home .feeds .sub-header{padding:0 8px}.simple-home .feeds .header .tab:nth-child(2),.simple-home .feeds .sub-header .tab:nth-child(2){margin-left:32px}.simple-home .feeds .header .online,.simple-home .feeds .sub-header .online{padding:8px 16px;height:32px;border-radius:16px;background-color:#8882;color:inherit;font-size:12px;display:flex;align-items:center;box-sizing:border-box}.simple-home .feeds .contents{grid-area:contents;display:flex;overflow:auto;--card-width:200px;--card-height:250px;--card-count:3;width:calc((var(--card-width) + 16px) * var(--card-count));padding-bottom:16px;scroll-snap-type:x mandatory;scrollbar-width:none!important}@media screen and (min-width:1050px){.simple-home .feeds .contents{--card-count:4}}@media screen and (min-width:1300px){.simple-home .feeds .contents{--card-count:5}}@media screen and (min-width:1600px){.simple-home .feeds .contents{--card-count:6}}@media screen and (min-width:1900px){.simple-home .feeds .contents{--card-count:7}}.simple-home .feeds .contents::-webkit-scrollbar{width:0!important;height:0!important}.simple-home .feeds .contents .card-wrapper{padding:0 8px;scroll-snap-align:start;flex-shrink:0}`,"simple-home-feeds-style");const i=[{name:"视频",type:"video",url:"https://t.bilibili.com/?tab=8"},{name:"番剧",type:"bangumi",url:"https://t.bilibili.com/?tab=512"}];return{export:Object.assign({template:a},{components:{VideoCard:()=>t.importAsync("video-card.vue"),Icon:()=>t.importAsync("icon.vue")},data(){return{online:"--",tabs:i,currentTab:i[0],feedCards:[]}},watch:{currentTab(e){this.updateFeedCards(e)}},methods:{async updateFeedCards(e){const{getVideoFeeds:a}=await t.importAsync("feeds-apis");this.feedCards=await a(e.type)},changeTab(e){if(this.currentTab===e){open(e.url,"_blank")}else{this.currentTab=e}}},async mounted(){this.updateFeedCards(this.currentTab);const e=await Ajax.getJson("https://api.bilibili.com/x/web-interface/online");if(e.code===0){this.online=e.data.web_online}}})}}})();

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
#app>.bili-wrapper,#app>.elevator-module,.bili-header-m .head-banner .head-content .head-logo,.international-footer,.international-header .b-wrap,.international-home>:not(.international-header){display:none!important}
#app>.bili-header-m.stardust-common>.bili-wrapper,#app>.bili-wrapper,#app>.elevator-module,.bili-header-m .head-banner .head-content .head-logo,.international-footer,.international-header .b-wrap,.international-home>:not(.international-header){display:none!important}

View File

@ -1 +1 @@
(()=>{return(e,m)=>{const o=`<div class=simplify-home><component class=simplify-home-component :is=activeComponent></component></div>`;m.applyStyleFromText(`.simplify-home{margin-top:32px;display:flex;align-items:center;justify-content:center}.simplify-home .simplify-home-component{max-width:100%}html{scroll-behavior:smooth}`,"simplify-home-style");return{export:Object.assign({template:o},{components:{"minimal-home":()=>m.importAsync("minimal-home.vue"),"simple-home":()=>m.importAsync("simple-home.vue")},computed:{activeComponent(){return this.homeStyle==="清爽"?"simple-home":"minimal-home"}},props:{homeStyle:String}})}}})();
(()=>{return(e,o)=>{const m=`<div class=simplify-home><component class=simplify-home-component :is=activeComponent></component></div>`;o.applyStyleFromText(`.simplify-home{padding-top:32px;display:flex;align-items:flex-start;justify-content:center;min-height:100vh;background-color:#f4f4f4}body.dark .simplify-home{background-color:#181818}.simplify-home .simplify-home-component{max-width:100%}html{scroll-behavior:smooth}`,"simplify-home-style");return{export:Object.assign({template:m},{components:{"minimal-home":()=>o.importAsync("minimal-home.vue"),"simple-home":()=>o.importAsync("simple-home.vue")},computed:{activeComponent(){return this.homeStyle==="清爽"?"simple-home":"minimal-home"}},props:{homeStyle:String}})}}})();

1
min/trending-videos.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(t,a)=>{const i=async(t,i)=>{const e=await Ajax.getJsonWithCredentials(`https://api.bilibili.com/x/web-interface/ranking/index?day=${t}`);if(i===undefined){const{getWatchlaterList:t}=await a.importAsync("watchlater-api");i=await t()}if(e.code!==0){throw new Error(e.message)}return e.data.map(a=>({id:a.aid+"-"+t,aid:parseInt(a.aid),title:a.title,upID:a.mid,upName:a.author,coverUrl:a.pic.replace("http://","https://"),description:a.description,durationText:a.duration,playCount:formatCount(a.play),coins:formatCount(a.coins),favorites:formatCount(a.favorites),watchlater:i.includes(parseInt(a.aid))}))};return{export:{getTrendingVideos:i}}}})();

1
min/trending-videos.vue.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(a,n)=>{const t=`<div class=trendings><div class=header><div class=title>热门</div><div class=tabs><div class=tab v-for="tab in tabs":key=tab.day @click=changeTab(tab) :class="{active: currentTab === tab}"><div class=tab-name>{{tab.name}}</div></div></div></div><div class=contents><div class=card-wrapper v-for="card in trendingCards":key=card.id><video-card :data=card orientation=vertical></video-card></div></div></div>`;n.applyStyleFromText(`.simple-home .trendings{display:flex;flex-direction:column}.simple-home .trendings .header{padding:0 8px}.simple-home .trendings .contents{--card-width:200px;--card-height:250px;--card-count:3;margin-top:16px;display:flex;overflow:auto;height:calc(var(--card-height) + 16px);width:calc((var(--card-width) + 16px) * var(--card-count));scroll-snap-type:x mandatory;scrollbar-width:none!important}@media screen and (max-width:1250px) and (min-width:900px){.simple-home .trendings .contents{--card-count:2}}@media screen and (max-width:1050px) and (min-width:900px){.simple-home .trendings .contents{--card-count:1}}@media screen and (min-width:1600px){.simple-home .trendings .contents{--card-count:4}}@media screen and (min-width:1900px){.simple-home .trendings .contents{--card-count:5}}.simple-home .trendings .contents::-webkit-scrollbar{width:0!important;height:0!important}.simple-home .trendings .contents .card-wrapper{padding:0 8px;scroll-snap-align:start;flex-shrink:0}`,"trending-videos-style");const e=[{name:"一周",day:7,url:"https://www.bilibili.com/ranking/all/0/0/7"},{name:"三日",day:3,url:"https://www.bilibili.com/ranking"},{name:"昨日",day:1,url:"https://www.bilibili.com/ranking/all/0/0/1"}];return{export:Object.assign({template:t},{components:{VideoCard:()=>n.importAsync("video-card.vue")},data(){return{tabs:e,currentTab:e[0],trendingCards:[]}},watch:{currentTab(a){this.updateTrendingTab(a)}},methods:{async updateTrendingTab(a){const{getTrendingVideos:t}=await n.importAsync("trending-videos");this.trendingCards=await t(a.day)},changeTab(a){if(this.currentTab===a){open(a.url,"_blank")}else{this.currentTab=a}}},mounted(){this.updateTrendingTab(this.currentTab)}})}}})();

1
min/video-card-info.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(r,e)=>{}})();

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>{return(i,t)=>{const a=`<div class=video-list><div class=loading v-if=loading><i class="mdi mdi-18px mdi-loading mdi-spin"></i>加载中...</div><div class=cards :class="{'show-rank': showRank}"v-else-if=cards.length><video-card v-for="card of cards":key=card.id :data=card></video-card></div><div class=empty v-else>空空如也哦 = ̄ω ̄=</div></div>`;t.applyStyleFromText(`.minimal-home .video-list .empty,.minimal-home .video-list .loading{height:48px;display:flex;align-items:center;justify-content:center;font-size:11pt;color:#707070}.minimal-home .video-list .empty .mdi,.minimal-home .video-list .loading .mdi{margin-right:8px}body.dark .minimal-home .video-list .empty,body.dark .minimal-home .video-list .loading{color:#eee}.minimal-home .video-list .cards{display:flex;flex-wrap:wrap;align-items:flex-end}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1),.minimal-home .video-list .cards.show-rank .video-card:nth-child(17),.minimal-home .video-list .cards.show-rank .video-card:nth-child(9){margin-top:48px}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1)::before,.minimal-home .video-list .cards.show-rank .video-card:nth-child(17)::before,.minimal-home .video-list .cards.show-rank .video-card:nth-child(9)::before{position:absolute;top:-42px;left:0;font-size:14pt;font-weight:700}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1)::before{content:"昨日"}.minimal-home .video-list .cards.show-rank .video-card:nth-child(9)::before{content:"三日"}.minimal-home .video-list .cards.show-rank .video-card:nth-child(17)::before{content:"一周"}`,"video-list-style");return{export:Object.assign({template:a},{components:{VideoCard:()=>t.importAsync("video-card.vue")},props:["showRank"],data(){return{cards:[],loading:true}},methods:{async getRankList(){const i=async i=>{const a=await Ajax.getJsonWithCredentials(`https://api.bilibili.com/x/web-interface/ranking/index?day=${i}`);const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const o=await e();if(a.code!==0){throw new Error(a.message)}this.cards.push(...a.data.map(t=>{return{id:t.aid+"-"+i,aid:parseInt(t.aid),title:t.title,upID:t.mid,upName:t.author,coverUrl:t.pic.replace("http://","https://"),description:t.description,durationText:t.duration,playCount:formatCount(t.play),coins:formatCount(t.coins),favorites:formatCount(t.favorites),watchlater:o.includes(t.aid)}}))};await Promise.all([1,3,7].map(i))},async getActivityVideos(){const i=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=8`);const{getWatchlaterList:a}=await t.importAsync("watchlater-api");const e=await a();if(i.code!==0){throw new Error(i.message)}this.cards=i.data.cards.map(i=>{const t=JSON.parse(i.card);const a=_.get(i,"display.topic_info.topic_details",[]).map(i=>{return{id:i.topic_id,name:i.topic_name}});return{id:i.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:i.desc.user_profile.info.uid,upName:i.desc.user_profile.info.uname,upFaceUrl:i.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:i.timestamp,time:new Date(i.timestamp*1e3),topics:a,dynamic:t.dynamic,like:formatCount(i.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:e.includes(t.aid)}})}},async mounted(){try{if(this.showRank){await this.getRankList()}else{await this.getActivityVideos()}}catch(i){Toast.error(i.message,this.showRank?"热门视频":"视频动态",3e3)}finally{this.loading=false}}})}}})();
(()=>{return(i,a)=>{const t=`<div class=video-list><div class=loading v-if=loading><i class="mdi mdi-18px mdi-loading mdi-spin"></i>加载中...</div><div class=cards :class="{'show-rank': showRank}"v-else-if=cards.length><video-card v-for="card of cards":key=card.id :data=card></video-card></div><div class=empty v-else>空空如也哦 = ̄ω ̄=</div></div>`;a.applyStyleFromText(`.minimal-home .video-list .empty,.minimal-home .video-list .loading{height:48px;display:flex;align-items:center;justify-content:center;font-size:11pt;color:#707070}.minimal-home .video-list .empty .mdi,.minimal-home .video-list .loading .mdi{margin-right:8px}body.dark .minimal-home .video-list .empty,body.dark .minimal-home .video-list .loading{color:#eee}.minimal-home .video-list .cards{display:flex;flex-wrap:wrap;align-items:flex-end}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1),.minimal-home .video-list .cards.show-rank .video-card:nth-child(17),.minimal-home .video-list .cards.show-rank .video-card:nth-child(9){margin-top:48px}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1)::before,.minimal-home .video-list .cards.show-rank .video-card:nth-child(17)::before,.minimal-home .video-list .cards.show-rank .video-card:nth-child(9)::before{position:absolute;top:-42px;left:0;font-size:14pt;font-weight:700}.minimal-home .video-list .cards.show-rank .video-card:nth-child(1)::before{content:"昨日"}.minimal-home .video-list .cards.show-rank .video-card:nth-child(9)::before{content:"三日"}.minimal-home .video-list .cards.show-rank .video-card:nth-child(17)::before{content:"一周"}`,"video-list-style");return{export:Object.assign({template:t},{components:{VideoCard:()=>a.importAsync("video-card.vue")},props:["showRank"],data(){return{cards:[],loading:true}},methods:{async getRankList(){const{getTrendingVideos:i}=await a.importAsync("trending-videos");const{getWatchlaterList:t}=await a.importAsync("watchlater-api");const e=await t();const o=async a=>{const t=await i(a,e);this.cards.push(...t)};await Promise.all([1,3,7].map(o))},async getActivityVideos(){const i=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=8`);const{getWatchlaterList:t}=await a.importAsync("watchlater-api");const e=await t();if(i.code!==0){throw new Error(i.message)}this.cards=i.data.cards.map(i=>{const a=JSON.parse(i.card);const t=_.get(i,"display.topic_info.topic_details",[]).map(i=>{return{id:i.topic_id,name:i.topic_name}});return{id:i.desc.dynamic_id_str,aid:a.aid,title:a.title,upID:i.desc.user_profile.info.uid,upName:i.desc.user_profile.info.uname,upFaceUrl:i.desc.user_profile.info.face,coverUrl:a.pic,description:a.desc,timestamp:i.timestamp,time:new Date(i.timestamp*1e3),topics:t,dynamic:a.dynamic,like:formatCount(i.desc.like),duration:a.duration,durationText:formatDuration(a.duration,0),playCount:formatCount(a.stat.view),danmakuCount:formatCount(a.stat.danmaku),watchlater:e.includes(a.aid)}})}},async mounted(){try{if(this.showRank){await this.getRankList()}else{await this.getActivityVideos()}}catch(i){Toast.error(i.message,this.showRank?"热门视频":"视频动态",3e3)}finally{this.loading=false}}})}}})();

View File

@ -1,3 +1,5 @@
import { VideoCardInfo } from '../style/simplify-home/video-card-info'
export interface FeedsCardType {
id: number
name: string
@ -96,7 +98,7 @@ class FeedsCardsManager extends EventTarget {
parseCard(element: HTMLElement): FeedsCard {
const getText = (selector: string) => {
if (element.querySelector(selector) === null) {
// console.log(element, selector)
console.warn(element, selector)
return ''
}
return (element.querySelector(selector) as HTMLElement).innerText
@ -166,9 +168,84 @@ class FeedsCardsManager extends EventTarget {
}
export const feedsCardsManager = new FeedsCardsManager()
export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promise<VideoCardInfo[]> => {
const json = await Ajax.getJsonWithCredentials(
`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${type === 'video' ? 8 : 512}`
)
if (json.code !== 0) {
throw new Error(json.message)
}
if (type === 'video') {
const { getWatchlaterList } = await import(
'../video/watchlater-api'
)
const watchlaterList = await getWatchlaterList()
return json.data.cards.map(
(c: any): VideoCardInfo => {
const card = JSON.parse(c.card)
const topics = _.get(c, 'display.topic_info.topic_details', []).map(
(it: any) => {
return {
id: it.topic_id,
name: it.topic_name
}
}
)
return {
id: c.desc.dynamic_id_str,
aid: card.aid,
title: card.title,
upID: c.desc.user_profile.info.uid,
upName: c.desc.user_profile.info.uname,
upFaceUrl: c.desc.user_profile.info.face,
coverUrl: card.pic,
description: card.desc,
timestamp: c.timestamp,
time: new Date(c.timestamp * 1000),
topics,
dynamic: card.dynamic,
like: formatCount(c.desc.like),
duration: card.duration,
durationText: formatDuration(card.duration, 0),
playCount: formatCount(card.stat.view),
danmakuCount: formatCount(card.stat.danmaku),
watchlater: watchlaterList.includes(card.aid)
}
}
)
} else if (type === 'bangumi') {
return json.data.cards.map(
(c: any): VideoCardInfo => {
const card = JSON.parse(c.card)
return {
id: c.desc.dynamic_id_str,
aid: card.aid,
epID: card.episode_id,
title: card.new_desc,
upName: card.apiSeasonInfo.title,
upFaceUrl: card.apiSeasonInfo.cover,
coverUrl: card.cover,
description: '',
timestamp: c.timestamp,
time: new Date(c.timestamp * 1000),
like: formatCount(c.desc.like),
durationText: '',
playCount: formatCount(card.play_count),
danmakuCount: formatCount(card.bullet_count),
watchlater: false,
}
}
)
} else {
return []
}
}
export default {
export: {
feedsCardsManager,
feedsCardTypes,
getVideoFeeds,
},
}

View File

@ -4,9 +4,10 @@ export const getScriptBlocker = async () => {
return scriptBlocker
}
let blockPatterns = (await GM.getValue('scriptBlockPatterns')) || []
// 开启简化首页时, 阻断所有其他的<script>
// 开启简化首页时, 阻断所有其他的非内联<script>
// 内联<script>含有一些页面初始化信息, 正好可以被利用
if (await GM.getValue('simplifyHome') && document.URL.replace(window.location.search, '') === 'https://www.bilibili.com/') {
blockPatterns = [/./]
blockPatterns = [/^[^<]./]
// 加个空函数避免一些图片 onload 里调用 reportfs 报错
unsafeWindow.reportfs = () => { }
}

View File

@ -117,6 +117,9 @@ export const formatDuration = (time, fixed = 0) => {
}
export const getDpiSourceSet = (src, baseSize, extension = 'jpg') => {
const dpis = [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4]
if (extension.startsWith('.')) {
extension = extension.substring(1)
}
return dpis.map(dpi => {
if (typeof baseSize === 'object') {
if ('width' in baseSize && 'height' in baseSize) {

View File

@ -943,6 +943,7 @@ const getActivityTabComponent = ({ dataObject, apiUrl, name, handleJson, templat
},
}
}
// https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_history?uid=39717974&offset_dynamic_id=311158827135150245&type=8
class Activities extends NavbarComponent {
constructor () {
super();

View File

@ -1,17 +1,43 @@
<template>
<img :width="width" :height="height" :srcset="srcset" :src="src" :style="{filter: blur ? 'blur(' + blur + 'px)' : undefined}">
<img :width="width" :height="height" :srcset="srcset" :src="actualSrc" :style="{filter: blur ? 'blur(' + blur + 'px)' : undefined}">
</template>
<script>
export default {
props: ['size', 'src', 'blur'],
computed: {
srcset () {
props: ['size', 'src', 'blur', 'root', 'rootMargin', 'threshold'],
data() {
return {
srcset: null,
actualSrc: null,
}
},
methods: {
calcSrc() {
if (!this.src || !this.size) {
return null
}
return getDpiSourceSet(this.src, this.size)
const extension = this.src.substring(this.src.lastIndexOf('.') + 1)
this.srcset = getDpiSourceSet(this.src, this.size, extension)
this.actualSrc = this.src
},
},
mounted() {
const options = {
root: this.root,
rootMargin: this.rootMargin || '200px',
threshold: this.threshold,
}
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.calcSrc()
observer.disconnect()
}
})
}, options)
observer.observe(this.$el)
},
computed: {
width () {
if (typeof this.size === 'object' && 'width' in this.size) {
return this.size.width

View File

@ -11,7 +11,7 @@
</template>
<script lang="ts">
import { VideoCardInfo } from '../video-card.vue'
import { VideoCardInfo } from '../video-card-info'
export default {
components: {
VideoCard: () => import('../video-card.vue')
@ -25,37 +25,14 @@ export default {
},
methods: {
async getRankList() {
const { getTrendingVideos } = await import('../trending-videos')
const { getWatchlaterList } = await import(
'../../../video/watchlater-api'
)
const watchlaterList = await getWatchlaterList()
const getRankListByDays = async (days: number) => {
const json = await Ajax.getJsonWithCredentials(
`https://api.bilibili.com/x/web-interface/ranking/index?day=${days}`
)
const { getWatchlaterList } = await import(
'../../../video/watchlater-api'
)
const watchlaterList = await getWatchlaterList()
if (json.code !== 0) {
throw new Error(json.message)
}
this.cards.push(
...json.data.map(
(card: any): VideoCardInfo => {
return {
id: card.aid + '-' + days,
aid: parseInt(card.aid),
title: card.title,
upID: card.mid,
upName: card.author,
coverUrl: card.pic.replace('http://', 'https://'),
description: card.description,
durationText: card.duration,
playCount: formatCount(card.play),
coins: formatCount(card.coins),
favorites: formatCount(card.favorites),
watchlater: watchlaterList.includes(card.aid)
}
}
)
)
const cards = await getTrendingVideos(days, watchlaterList)
this.cards.push(...cards)
}
await Promise.all([1, 3, 7].map(getRankListByDays))
},
@ -155,13 +132,13 @@ export default {
}
}
.video-card:nth-child(1)::before {
content: "昨日";
content: '昨日';
}
.video-card:nth-child(9)::before {
content: "三日";
content: '三日';
}
.video-card:nth-child(17)::before {
content: "一周";
content: '一周';
}
}
}

View File

@ -0,0 +1,39 @@
export interface Blackboard {
url: string
title: string
isAd: boolean
imageUrl: string
}
export const getBlackboards = async (): Promise<Blackboard[]> => {
if (dq('.international-home')) {
const initData = await SpinQuery.condition(() => unsafeWindow['__INITIAL_STATE__'], it => it !== undefined)
return dqa('.home-slide .item')
.map((it, index) => {
const locID = it.querySelector('a')!.getAttribute('data-loc-id')!
return {
url: initData.locsData[locID][index].url,
title: (it.querySelector('.title') as HTMLElement).innerText!.trim(),
isAd: Boolean(it.querySelector('.gg-icon')),
imageUrl: it.querySelector('img')!.getAttribute('src')!.replace(/@.+$/, ''),
} as Blackboard
})
} else {
const panel = dq('.chief-recommend-module .panel') as HTMLElement
const images = panel.querySelector('.pic') as HTMLElement
const titles = panel.querySelectorAll('.title > a')
return [...images.querySelectorAll('li')].map((li, index) => {
const title = titles[index] as HTMLElement
return {
url: title.getAttribute('href'),
title: title.innerText!.trim(),
isAd: Boolean(title.querySelector('.gg-pic')),
imageUrl: li.querySelector('img')!.getAttribute('src')!.replace(/@.+$/, ''),
} as Blackboard
})
}
}
export default {
export: {
getBlackboards,
},
}

View File

@ -0,0 +1,139 @@
<template>
<div class="blackboards">
<div class="header">
<div class="title">活动</div>
<a class="more" href="https://www.bilibili.com/blackboard/x/act_list/" target="_blank">
<icon type="mdi" icon="dots-horizontal"></icon>更多
</a>
</div>
<input
class="hidden-input blackboard-radio"
type="radio"
name="blackboard"
v-for="(b, i) of blackboards"
:checked="i === 0"
:id="'blackboard' + i"
:data-index="i"
:key="i"
/>
<div class="jump-dots">
<label v-for="(b, i) of blackboards" :for="'blackboard' + i" :key="i">
<div class="jump-dot"></div>
</label>
</div>
<div class="blackboard-cards">
<a
class="blackboard-card"
target="_blank"
v-for="(b, i) of blackboards"
:key="i"
:href="b.url"
:title="b.title"
>
<dpi-img :src="b.imageUrl" :alt="b.title" :size="{width: 500, height: 250}" :root="cardsContainer"></dpi-img>
<div class="title">{{b.title}}</div>
</a>
</div>
</div>
</template>
<script lang="ts">
import { Blackboard } from './blackboard'
export default {
components: {
Icon: () => import('../../icon.vue'),
'dpi-img': () => import('../../dpi-img.vue'),
},
data() {
return {
blackboards: [] as Blackboard[],
interval: 0
}
},
destroyed() {
if (this.interval) {
clearInterval(this.interval)
}
},
computed: {
cardsContainer() {
return this.$el.querySelector('.blackboard-cards')
}
},
async mounted() {
const { getBlackboards } = await import('./blackboard')
this.blackboards = (await getBlackboards()).filter(it => !it.isAd)
const blackboards = dq('.blackboards') as HTMLDivElement
this.interval = setInterval(() => {
if (!document.hasFocus() || blackboards.matches('.blackboards:hover')) {
return
}
const currentIndex = parseInt(
dq(`.blackboard-radio:checked`)!.getAttribute('data-index')!
)
let targetIndex: number
if (currentIndex === this.blackboards.length - 1) {
targetIndex = 0
} else {
targetIndex = currentIndex + 1
}
;(dq(
`.blackboard-radio[data-index='${targetIndex}']`
) as HTMLInputElement).checked = true
}, 5000)
}
}
</script>
<style lang="scss">
$first-row-height: 250px;
.simple-home .blackboards {
display: grid;
grid-template-areas: 'header header' 'dots cards';
grid-template-columns: 8px 1fr;
grid-template-rows: 1fr $first-row-height;
row-gap: 16px;
column-gap: 16px;
align-self: start;
.blackboard-cards {
grid-area: cards;
--blackboard-width: 500px;
--blackboard-height: 250px;
width: var(--blackboard-width);
height: var(--blackboard-height);
border-radius: 16px;
overflow: hidden;
.blackboard-card {
width: 100%;
height: 100%;
position: relative;
display: block;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
img {
width: 100%;
height: 100%;
object-fit: fill;
display: block;
}
.title {
position: absolute;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
padding: 4px 16px;
color: white;
background-color: #000a;
font-size: 14px;
font-weight: bold;
border-radius: 14px;
white-space: nowrap;
opacity: 0;
}
&:hover .title {
opacity: 1;
}
}
}
}
</style>

View File

@ -0,0 +1,21 @@
<template>
<div class="categories">
<div class="header">
<div class="title">分区</div>
</div>
快了, 已经在路上了.jpg
</div>
</template>
<script lang="ts">
export default {
}
</script>
<style lang="scss">
.simple-home .categories {
display: flex;
flex-direction: column;
}
</style>

View File

@ -0,0 +1,176 @@
<template>
<div class="info-row">
<div class="header">
<div class="title">栏目</div>
</div>
<!-- <a
class="online"
target="_blank"
href="https://www.bilibili.com/video/online.html"
>在线人数: {{online}}</a>-->
<div class="entries">
<a
class="entry"
v-for="entry of entries"
:key="entry.name"
:href="entry.url"
target="_blank"
:style="{backgroundColor: entry.color}"
>
<svg class="icon" viewBox="0 0 1024 1024" v-html="entry.icon" />
{{entry.name}}
</a>
</div>
</div>
</template>
<script lang="ts">
interface InfoEntry {
name: string
url: string
color: string
icon: string
}
const entries: InfoEntry[] = [
{
name: '专栏',
url: 'https://www.bilibili.com/read/home',
color: '#62E2FF40',
icon: `
<path
d="M778.496 142.08h-537.6a56.832 56.832 0 0 0-60.16 54.016v630.528a56.832 56.832 0 0 0 59.136 54.016h537.6a56.832 56.832 0 0 0 59.136-54.016V196.096a56.832 56.832 0 0 0-59.136-54.016z"
fill="#54E2E2"></path>
<path
d="M298.496 679.168h421.376a25.6 25.6 0 0 0 0-52.736H298.496a25.6 25.6 0 1 0 0 52.736zM719.872 732.928H298.496a25.6 25.6 0 1 0 0 52.736h421.376a25.6 25.6 0 0 0 0-52.736z"
fill="#23ADE5"></path>
<path
d="M272.128 237.056m80.128 0l314.112 0q80.128 0 80.128 80.128l0 154.368q0 80.128-80.128 80.128l-314.112 0q-80.128 0-80.128-80.128l0-154.368q0-80.128 80.128-80.128Z"
fill="#23ADE5"></path>
<path d="M404.992 361.472m-49.408 0a49.408 49.408 0 1 0 98.816 0 49.408 49.408 0 1 0-98.816 0Z" fill="#2EC3E5">
</path>
<path d="M375.552 551.936l120.832-144.384a44.544 44.544 0 0 1 68.352 0l120.832 144.384z" fill="#2EC3E5"></path>
`
},
{
name: '直播',
url: 'https://live.bilibili.com/',
color: '#A5B8FF40',
icon: `
<path d="M392.448 332.8a92.416 92.416 0 1 1-92.416-92.416A92.416 92.416 0 0 1 392.448 332.8" fill="#23ADE5">
</path>
<path
d="M572.928 426.24A143.872 143.872 0 1 0 429.312 281.6a143.872 143.872 0 0 0 143.616 144.64zM826.624 521.472l-63.744 36.864v-48.64A72.192 72.192 0 0 0 691.2 437.76H190.72a72.192 72.192 0 0 0-71.936 71.936v295.424a71.936 71.936 0 0 0 71.936 71.936H691.2a71.936 71.936 0 0 0 71.936-71.936v-23.808L826.624 819.2a51.2 51.2 0 0 0 76.8-44.544V565.76a51.2 51.2 0 0 0-76.8-44.288z"
fill="#48CFE5"></path>
<path
d="M425.216 569.856l124.16 71.936a25.6 25.6 0 0 1 0 42.496l-124.16 71.68a25.6 25.6 0 0 1-37.12-21.248v-143.36a25.6 25.6 0 0 1 37.12-21.504"
fill="#FDDE80"></path>
`
},
{
name: '话题',
url: 'https://www.bilibili.com/blackboard/topic_list.html',
color: '#A1FF8040',
icon: `
<path
d="M880.64 520.448C880.64 642.56 768 742.4 627.712 742.4H409.6l-165.632 74.496-92.928-258.56a146.688 146.688 0 0 1-3.072-37.888v-37.888c0-122.112 110.592-226.56 250.112-226.56h232.704c136.448 0 249.856 104.448 249.856 226.56v37.888zM642.304 209.408h-256a280.064 280.064 0 0 0-279.04 273.152v43.776a250.88 250.88 0 0 0 3.072 46.336L215.04 878.08l183.04-90.112h244.224c153.6 0 279.04-116.48 279.04-261.632v-43.776a279.808 279.808 0 0 0-279.04-273.152z m58.112 351.744a51.2 51.2 0 0 1-51.2-51.2 55.552 55.552 0 0 1 58.112-52.48 54.528 54.528 0 0 1 51.2 55.296 57.088 57.088 0 0 1-58.112 49.408m-179.2 0a51.2 51.2 0 0 1-51.2-51.2 55.552 55.552 0 0 1 58.112-52.48 54.528 54.528 0 0 1 51.2 55.296A59.392 59.392 0 0 1 521.216 563.2m-179.2 0a51.2 51.2 0 0 1-51.2-51.2 55.552 55.552 0 0 1 58.112-52.48 54.528 54.528 0 0 1 51.2 55.296 59.648 59.648 0 0 1-58.112 49.408m279.04-270.336h-208.384c-122.112 0-224 87.296-224 188.928V512a111.36 111.36 0 0 0 3.072 31.744L267.264 768l110.592-58.112H645.12A194.048 194.048 0 0 0 842.752 512v-29.44c-2.816-104.448-102.4-191.744-223.744-191.744"
fill="#8FC31F"></path>
`
},
{
name: '小黑屋',
url: 'https://www.bilibili.com/blackroom/',
color: '#FFD29E40',
icon: `
<path
d="M139.264 529.152a27.136 27.136 0 0 1-14.592-2.816A32 32 0 0 1 113.152 486.4l130.816-236.032a28.416 28.416 0 1 1 49.152 28.928l-130.56 235.52a25.6 25.6 0 0 1-23.296 14.336"
fill="#F99E4A"></path>
<path
d="M380.416 529.152a34.56 34.56 0 0 1-25.6-14.592l-131.328-235.264a30.208 30.208 0 0 1 11.52-37.632 25.6 25.6 0 0 1 37.888 11.52l130.816 235.264a25.6 25.6 0 0 1-11.776 37.888c-2.816 0-8.704 2.816-11.52 2.816m261.376 0a25.6 25.6 0 0 1-14.336-2.816 29.44 29.44 0 0 1-11.776-37.888l130.816-235.264a28.928 28.928 0 0 1 37.632-11.52 29.44 29.44 0 0 1 11.776 37.632L665.6 514.56a25.6 25.6 0 0 1-23.296 14.592"
fill="#F99E4A"></path>
<path
d="M883.968 529.152a34.56 34.56 0 0 1-25.6-14.336l-130.56-235.52a27.392 27.392 0 0 1 11.52-37.632 25.6 25.6 0 0 1 37.888 11.52l130.56 235.52a25.6 25.6 0 0 1-11.776 37.632c-2.816 0-8.704 2.816-11.776 2.816"
fill="#F99E4A"></path>
<path
d="M801.536 241.664l-130.56-51.2A129.536 129.536 0 0 0 640 183.552H380.416a153.6 153.6 0 0 0-32 5.632L217.6 241.664A21.248 21.248 0 0 0 226.304 281.6h569.6a21.248 21.248 0 0 0 5.632-40.704M458.752 281.6v520.704a51.2 51.2 0 0 0 104.704 0V281.6z"
fill="#FFD043"></path>
<path d="M561.152 183.296A51.2 51.2 0 0 0 512 139.776a52.992 52.992 0 0 0-51.2 46.336h102.4z" fill="#FFD043">
</path>
<path
d="M755.2 877.824H267.008A41.472 41.472 0 0 1 230.4 816.896l55.04-122.112a44.8 44.8 0 0 1 37.888-25.6h373.76a37.12 37.12 0 0 1 37.632 25.6L790.016 819.2a37.888 37.888 0 0 1-34.816 58.112"
fill="#F99E4A"></path>
<path
d="M900.352 494.336a9.216 9.216 0 0 1 8.704 8.704 148.48 148.48 0 0 1-296.192 0 7.68 7.68 0 0 1 8.704-8.704z m-502.528 0a9.216 9.216 0 0 1 8.704 8.704 151.808 151.808 0 0 1-148.224 142.336 150.016 150.016 0 0 1-148.224-142.336 7.68 7.68 0 0 1 8.704-8.704z"
fill="#FFD043"></path>
`
}
]
export default {
components: {
Icon: () => import('../../icon.vue')
},
data() {
return {
entries
}
}
}
</script>
<style lang="scss">
.simple-home .info-row {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.entries {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-around;
height: 100%;
margin-top: 16px;
padding-bottom: 16px;
.entry {
display: flex;
align-items: center;
border-radius: 8px;
font-size: 14px;
color: inherit;
box-sizing: border-box;
flex: 0 0 auto;
height: 36px;
justify-content: center;
padding: 0px 12px 0 8px;
.icon {
width: 24px;
height: 24px;
transition-duration: 0.5s;
margin-right: 8px;
}
&:hover .icon {
transform: rotate(360deg);
}
// &:not(:last-child) {
// margin-bottom: 24px;
// }
// @media screen and (max-width: 900px) {
// &:not(:last-child) {
// margin-right: 16px;
// }
// }
}
@media screen and (max-width: 900px) {
flex-direction: row;
.entry {
flex: 1 0 0;
&:not(:last-child) {
margin-right: 16px;
}
}
}
}
}
</style>

View File

@ -0,0 +1,228 @@
<template>
<div class="feeds">
<div class="header">
<div class="tabs">
<div class="title">动态</div>
<div
class="tab"
v-for="tab in tabs"
:key="tab.type"
@click="changeTab(tab)"
:class="{active: currentTab === tab}"
>
<div class="tab-name">{{tab.name}}</div>
</div>
</div>
<a
class="online"
target="_blank"
href="https://www.bilibili.com/video/online.html"
>在线人数: {{online}}</a>
<a class="more" href="//t.bilibili.com/" target="_blank">
<icon type="home" icon="activity"></icon>全部动态
</a>
</div>
<div class="contents">
<div class="card-wrapper" v-for="card in feedCards" :key="card.id">
<video-card :data="card" orientation="vertical"></video-card>
</div>
</div>
<!-- <div class="video-feeds">
<div class="sub-header">视频</div>
<div class="contents">
<div class="card-wrapper" v-for="card in videoFeeds" :key="card.id">
<video-card :data="card" orientation="vertical"></video-card>
</div>
</div>
</div>
<div class="bangumi-feeds">
<div class="sub-header">番剧</div>
<div class="contents">
<div class="card-wrapper" v-for="card in bangumiFeeds" :key="card.id">
<video-card :data="card" orientation="vertical"></video-card>
</div>
</div>
</div>-->
</div>
</template>
<script lang="ts">
interface Tab {
name: string
type: 'video' | 'bangumi'
url: string
}
const tabs: Tab[] = [
{
name: '视频',
type: 'video',
url: 'https://t.bilibili.com/?tab=8'
},
{
name: '番剧',
type: 'bangumi',
url: 'https://t.bilibili.com/?tab=512'
}
]
export default {
components: {
VideoCard: () => import('../video-card.vue'),
Icon: () => import('../../icon.vue')
},
data() {
return {
online: '--',
tabs,
currentTab: tabs[0],
feedCards: []
}
},
watch: {
currentTab(tab: Tab) {
this.updateFeedCards(tab)
}
},
methods: {
async updateFeedCards(tab: Tab) {
const { getVideoFeeds } = await import('../../../activity/feeds-apis')
this.feedCards = await getVideoFeeds(tab.type)
},
changeTab(tab: Tab) {
if (this.currentTab === tab) {
open(tab.url, '_blank')
} else {
this.currentTab = tab
}
}
},
async mounted() {
this.updateFeedCards(this.currentTab)
// const { getVideoFeeds } = await import('../../../activity/feeds-apis')
// this.videoFeeds = await getVideoFeeds('video')
// this.bangumiFeeds = await getVideoFeeds('bangumi')
const json = await Ajax.getJson(
'https://api.bilibili.com/x/web-interface/online'
)
if (json.code === 0) {
this.online = json.data.web_online
}
}
}
</script>
<style lang="scss">
.simple-home .feeds {
justify-self: start;
// display: flex;
// align-items: stretch;
// flex-direction: column;
display: grid;
grid-template-areas: 'header header' 'contents contents';
grid-template-columns: repeat(2, auto);
grid-template-rows: repeat(2, auto);
row-gap: 16px;
column-gap: 16px;
.header,
.sub-header {
padding: 0 8px;
.tab:nth-child(2) {
margin-left: 32px;
}
.online {
padding: 8px 16px;
height: 32px;
border-radius: 16px;
background-color: #8882;
color: inherit;
font-size: 12px;
display: flex;
align-items: center;
box-sizing: border-box;
}
}
.contents {
grid-area: contents;
display: flex;
overflow: auto;
--card-width: 200px;
--card-height: 250px;
--card-count: 3;
width: calc((var(--card-width) + 16px) * var(--card-count));
padding-bottom: 16px;
scroll-snap-type: x mandatory;
scrollbar-width: none !important;
@media screen and (min-width: 1050px) {
--card-count: 4;
}
@media screen and (min-width: 1300px) {
--card-count: 5;
}
@media screen and (min-width: 1600px) {
--card-count: 6;
}
@media screen and (min-width: 1900px) {
--card-count: 7;
}
&::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
.card-wrapper {
padding: 0 8px;
scroll-snap-align: start;
flex-shrink: 0;
}
}
// .video-feeds,
// .bangumi-feeds {
// display: flex;
// flex-direction: column;
// --card-width: 200px;
// --card-height: 250px;
// --card-count: 1;
// .contents {
// width: calc((var(--card-width) + 16px) * var(--card-count));
// padding-bottom: 16px;
// margin-top: 16px;
// display: flex;
// overflow: auto;
// scroll-snap-type: x mandatory;
// scrollbar-width: none !important;
// &::-webkit-scrollbar {
// width: 0 !important;
// height: 0 !important;
// }
// .card-wrapper {
// padding: 0 8px;
// scroll-snap-align: start;
// flex-shrink: 0;
// }
// }
// }
// .video-feeds {
// grid-area: video;
// @media screen and (min-width: 800px) {
// --card-count: 2;
// }
// @media screen and (min-width: 1180px) {
// --card-count: 3;
// }
// @media screen and (min-width: 1700px) {
// --card-count: 4;
// }
// }
// .bangumi-feeds {
// grid-area: bangumi;
// justify-self: end;
// @media screen and (min-width: 950px) {
// --card-count: 2;
// }
// @media screen and (min-width: 1450px) {
// --card-count: 3;
// }
// @media screen and (min-width: 1900px) {
// --card-count: 4;
// }
// }
}
</style>

View File

@ -1,10 +1,202 @@
<template>
<div class="simple-home">
快了, 已经在路上了.jpg
<blackboards></blackboards>
<trending-videos></trending-videos>
<info-row></info-row>
<feeds></feeds>
<categories></categories>
</div>
</template>
<script lang="ts">
export default {
components: {
Blackboards: () => import('./blackboard.vue'),
TrendingVideos: () => import('./trending-videos.vue'),
InfoRow: () => import('./online-info-row.vue'),
Feeds: () => import('./simple-home-feeds.vue'),
Categories: () => import('./categories/simple-home-categories.vue'),
}
}
</script>
<style lang="scss">
.simple-home {
--title-color: black;
color: #444;
display: grid;
grid-template-areas:
'blackboards trendings trendings'
'feeds feeds info'
'categories categories categories';
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(3, auto);
column-gap: 44px;
row-gap: 16px;
&,
& * {
transition: 0.2s ease-out;
}
body.dark & {
--title-color: white;
color: #ddd;
}
.jump-dots {
grid-area: dots;
align-self: center;
justify-self: center;
& label {
display: block;
}
& label:not(:last-child) {
margin-bottom: 6px;
}
.jump-dot {
background-color: #ddd;
width: 8px;
height: 20px;
border-radius: 8px;
cursor: pointer;
body.dark & {
background-color: #444;
}
}
}
.hidden-input {
display: none;
@for $i from 1 to 16 {
&:checked:nth-of-type(#{$i})
~ .jump-dots
label:nth-child(#{$i})
.jump-dot {
background-color: var(--theme-color);
height: 40px;
}
&:checked:nth-of-type(#{$i}) ~ .blackboard-cards .blackboard-card {
transform: translateY(calc(-1 * #{$i - 1} * var(--blackboard-height)));
}
}
}
.more {
cursor: pointer;
padding: 4px 12px 4px 8px;
display: flex;
align-items: center;
border-radius: 16px;
font-size: 13px;
font-weight: bold;
.be-icon {
margin-right: 8px;
transition: 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
font-size: 22px;
font-weight: normal;
}
&:hover {
.be-icon {
transform: rotate(180deg);
}
}
&,
&.hover {
color: inherit !important;
background-color: #ddd !important;
}
body.dark &,
body.dark &:hover {
color: inherit !important;
background-color: #333 !important;
}
}
.header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
.title {
color: var(--title-color);
font-weight: bold;
font-size: 22px;
}
.tabs {
display: flex;
align-items: center;
.tab {
cursor: pointer;
position: relative;
.tab-name {
opacity: 0.5;
font-size: 14px;
}
&:not(:last-child) {
margin-right: 24px;
}
&::after {
content: '';
width: calc(80%);
height: 3px;
border-radius: 2px;
position: absolute;
background-color: var(--theme-color);
left: 10%;
bottom: -6px;
transform: scaleX(0);
transition: 0.2s ease-out;
}
&.active::after {
transform: scaleX(1);
}
&.active .tab-name {
font-weight: bold;
opacity: 1;
transform: scale(1.1);
}
}
}
}
.sub-header {
color: var(--title-color);
font-weight: bold;
font-size: 18px;
display: flex;
align-items: center;
&::before {
content: '';
display: block;
width: 12px;
height: 12px;
background-color: var(--theme-color);
border-radius: 50%;
margin-right: 8px;
}
}
.blackboards {
grid-area: blackboards;
justify-self: start;
}
.trendings {
grid-area: trendings;
transform: translateX(8px);
justify-self: end;
}
.info-row {
grid-area: info;
justify-self: end;
}
.feeds {
grid-area: feeds;
transform: translateX(-8px);
justify-self: start;
}
.categories {
grid-area: categories;
}
@media screen and (max-width: 900px) {
& {
grid-template-areas: 'blackboards' 'trendings' 'info' 'feeds' 'categories';
grid-template-columns: 1fr;
grid-template-rows: repeat(5, auto);
.blackboards, .trendings, .info-row, .feeds, .categories {
justify-self: center;
}
}
}
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<div class="trendings">
<div class="header">
<div class="title">热门</div>
<div class="tabs">
<div
class="tab"
v-for="tab in tabs"
:key="tab.day"
@click="changeTab(tab)"
:class="{active: currentTab === tab}"
>
<div class="tab-name">{{tab.name}}</div>
</div>
</div>
</div>
<div class="contents">
<div class="card-wrapper" v-for="card in trendingCards" :key="card.id">
<video-card :data="card" orientation="vertical"></video-card>
</div>
</div>
</div>
</template>
<script lang="ts">
interface Tab {
name: string
day: number
url: string
}
const tabs: Tab[] = [
{
name: '一周',
day: 7,
url: 'https://www.bilibili.com/ranking/all/0/0/7',
},
{
name: '三日',
day: 3,
url: 'https://www.bilibili.com/ranking',
},
{
name: '昨日',
day: 1,
url: 'https://www.bilibili.com/ranking/all/0/0/1',
}
]
export default {
components: {
VideoCard: () => import('../video-card.vue'),
},
data() {
return {
tabs,
currentTab: tabs[0],
trendingCards: []
}
},
watch: {
currentTab(tab: Tab) {
this.updateTrendingTab(tab)
}
},
methods: {
async updateTrendingTab(tab: Tab) {
const { getTrendingVideos } = await import('../trending-videos')
this.trendingCards = await getTrendingVideos(tab.day)
},
changeTab(tab: Tab) {
if (this.currentTab === tab) {
open(tab.url, '_blank')
} else {
this.currentTab = tab
}
}
},
mounted() {
this.updateTrendingTab(this.currentTab)
},
}
</script>
<style lang="scss">
.simple-home .trendings {
display: flex;
flex-direction: column;
.header {
padding: 0 8px;
}
.contents {
--card-width: 200px;
--card-height: 250px;
--card-count: 3;
margin-top: 16px;
display: flex;
overflow: auto;
height: calc(var(--card-height) + 16px);
width: calc((var(--card-width) + 16px) * var(--card-count));
scroll-snap-type: x mandatory;
scrollbar-width: none !important;
@media screen and (max-width: 1250px) and (min-width: 900px) {
& {
--card-count: 2;
}
}
@media screen and (max-width: 1050px) and (min-width: 900px) {
& {
--card-count: 1;
}
}
@media screen and (min-width: 1600px) {
& {
--card-count: 4;
}
}
@media screen and (min-width: 1900px) {
& {
--card-count: 5;
}
}
&::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
.card-wrapper {
padding: 0 8px;
scroll-snap-align: start;
flex-shrink: 0;
}
}
}
</style>

View File

@ -3,6 +3,7 @@
.international-footer,
#app > .bili-wrapper,
#app > .elevator-module,
#app > .bili-header-m.stardust-common > .bili-wrapper,
.bili-header-m .head-banner .head-content .head-logo {
display: none !important;
}

View File

@ -21,11 +21,16 @@ export default {
</script>
<style lang="scss">
.simplify-home {
margin-top: 32px;
padding-top: 32px;
display: flex;
align-items: center;
align-items: flex-start;
justify-content: center;
min-height: 100vh;
background-color: #f4f4f4;
body.dark & {
background-color: #181818;
}
.simplify-home-component {
max-width: 100%;
}

View File

@ -0,0 +1,36 @@
import { VideoCardInfo } from './video-card-info'
export const getTrendingVideos = async (days: number, watchlaterList?: number[]): Promise<VideoCardInfo[]> => {
const json = await Ajax.getJsonWithCredentials(
`https://api.bilibili.com/x/web-interface/ranking/index?day=${days}`
)
if (watchlaterList === undefined) {
const { getWatchlaterList } = await import(
'../../video/watchlater-api'
)
watchlaterList = await getWatchlaterList()
}
if (json.code !== 0) {
throw new Error(json.message)
}
return json.data.map(
(card: any) => ({
id: card.aid + '-' + days,
aid: parseInt(card.aid),
title: card.title,
upID: card.mid,
upName: card.author,
coverUrl: card.pic.replace('http://', 'https://'),
description: card.description,
durationText: card.duration,
playCount: formatCount(card.play),
coins: formatCount(card.coins),
favorites: formatCount(card.favorites),
watchlater: watchlaterList!.includes(parseInt(card.aid))
})
)
}
export default {
export: {
getTrendingVideos,
},
}

View File

@ -0,0 +1,27 @@
export interface VideoCardInfo {
id: string
aid?: number
epID?: number
title: string
upID?: number
upName: string
upFaceUrl?: string
coverUrl: string
description: string
duration?: number
durationText: string
playCount: string
danmakuCount?: string
dynamic?: string
like?: string
coins?: string
favorites?: string
timestamp?: number
time?: Date
topics?: {
id: number
name: string
}[]
watchlater: boolean
}

View File

@ -1,9 +1,14 @@
<template>
<a class="video-card" target="_blank" :href="'https://www.bilibili.com/av' + aid">
<a
class="video-card"
target="_blank"
:href="epID ? ('https://www.bilibili.com/bangumi/play/ep' + epID) : ('https://www.bilibili.com/av' + aid)"
:class="{vertical: orientation === 'vertical'}"
>
<div class="cover-container">
<dpi-img class="cover" :src="coverUrl" :size="{height: 120, width: 200}"></dpi-img>
<div class="duration">{{durationText}}</div>
<div class="watchlater" @click.stop.prevent="toggleWatchlater()">
<div v-if="durationText" class="duration">{{durationText}}</div>
<div v-if="durationText" class="watchlater" @click.stop.prevent="toggleWatchlater()">
<i class="mdi" :class="{'mdi-clock-outline': !watchlater, 'mdi-check-circle': watchlater}"></i>
{{watchlater ? '已添加' : '稍后再看'}}
</div>
@ -23,18 +28,18 @@
class="up"
:class="{'no-face': !upFaceUrl}"
target="_blank"
:href="'https://space.bilibili.com/' + upID"
:href="upID ? ('https://space.bilibili.com/' + upID) : null"
>
<dpi-img v-if="upFaceUrl" class="face" :src="upFaceUrl" :size="24"></dpi-img>
<Icon v-else icon="up" type="extended"></Icon>
<div class="name" :title="upName">{{upName}}</div>
</a>
<div class="stats">
<template v-if="like">
<template v-if="like && !vertical">
<Icon type="extended" icon="like-outline"></Icon>
{{like}}
</template>
<template v-if="coins">
<template v-if="coins && !vertical">
<Icon type="home" icon="coin-outline"></Icon>
{{coins}}
</template>
@ -53,33 +58,9 @@
</template>
<script lang="ts">
export interface VideoCardInfo {
id: string
aid: number
title: string
upID: number
upName: string
upFaceUrl?: string
coverUrl: string
description: string
duration?: number
durationText: string
playCount: string
danmakuCount?: string
dynamic?: string
like?: string
coins?: string
favorites?: string
timestamp?: number
time?: Date
topics?: {
id: number
name: string
}[]
watchlater: boolean
}
import { VideoCardInfo } from './video-card-info'
export default {
props: ['data'],
props: ['data', 'orientation'],
components: {
'dpi-img': () => import('../dpi-img.vue'),
Icon: () => import('../icon.vue')
@ -93,9 +74,16 @@ export default {
favorites: '',
dynamic: '',
topics: [],
upID: 0,
epID: 0,
...this.data
} as VideoCardInfo
},
computed: {
vertical() {
return this.orientation === 'vertical'
}
},
methods: {
async toggleWatchlater() {
try {
@ -125,8 +113,9 @@ export default {
height: var(--card-height);
width: var(--card-width);
color: black;
background-color: #fff;
border-radius: 16px;
box-shadow: 0 2px 6px 0 #0002;
box-shadow: 0 4px 8px 0 #0001;
margin-right: var(--card-margin);
margin-bottom: var(--card-margin);
position: relative;
@ -139,14 +128,62 @@ export default {
&:hover {
color: black;
}
&.vertical {
grid-template-columns: auto auto;
grid-template-rows: 2fr 1fr 1fr;
grid-template-areas:
'cover cover'
'title title'
'up up';
.description,
.topics {
display: none;
}
.cover-container {
border-radius: 16px 16px 0 0;
}
.title {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
max-height: 3em;
word-break: break-all;
white-space: normal;
line-height: 1.5;
font-size: 11pt;
}
.up {
align-self: start;
white-space: nowrap;
.name {
text-overflow: ellipsis;
overflow: hidden;
}
&:not(.no-face) {
margin-left: 8px;
max-width: calc(var(--card-width) - 16px);
}
&.no-face {
margin-top: 8px;
max-width: calc(var(--card-width) - 24px);
}
}
.stats {
align-self: end;
justify-self: start;
margin-bottom: 8px;
margin-right: 0;
}
}
& > * {
justify-self: self-start;
align-self: center;
}
&:hover {
transform: scale(1.02);
transition: 0.1s cubic-bezier(0.39, 0.58, 0.57, 1);
.cover {
transform: scale(1.05);
transition: 0.1s cubic-bezier(0.39, 0.58, 0.57, 1);
}
.duration,
.watchlater {
opacity: 1;
@ -159,10 +196,15 @@ export default {
.cover-container {
grid-area: cover;
border-radius: 16px 0 0 16px;
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
.cover {
border-radius: 16px 0 0 16px;
object-fit: cover;
width: 100%;
height: 100%;
}
& > :not(.cover) {
position: absolute;
@ -272,9 +314,12 @@ export default {
.name {
margin: 0 8px;
}
&:hover {
&:not(.no-face):hover {
background-color: #8884;
.name {
}
&:hover {
.name,
.be-icon {
color: var(--theme-color);
}
}