mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add favorites list navbar component
This commit is contained in:
parent
b22060fdaa
commit
02e2b4539e
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
@ -30,13 +30,14 @@
|
||||
"compact-layout.min.js": "B20609A7CBBDB1845FA0156FB5BE6B1E1A1B8B069EA85F65D16241DD2C12D738",
|
||||
"custom-control-background.min.css": "1981FD2BF3B17ECF33F98D5DEDAF0D32ACBE9532A51FDB70822286991AB98EF3",
|
||||
"custom-control-background.min.js": "2A439B045A51D24F5115DD25995ED37E3D0371A074199FE6C727F2235F39C4D9",
|
||||
"custom-navbar.min.css": "BC8741D8949DEEBD3A745292A139B639A54C43E8015D348649EF09228A1A568A",
|
||||
"custom-navbar.min.css": "B6EF1AF22222A5F10B648D57494B4148B3E264B7D3F1EE5B0047BEBB51DFC2FB",
|
||||
"custom-navbar.min.html": "17FD1B1727E8D62E7997F10002FE7BF23472F390042D44DE3376A7A5A5FF2FDF",
|
||||
"custom-navbar.min.js": "10A4390317FA65E016F29953B0FF9FD70C7E39AAB4E883A563B3EE21B33B7249",
|
||||
"custom-navbar.min.js": "3CBF688BE1F0FD3AEFFB6268328FEEC5B1BB189EC0F53C6B86E4D9353AE67DE7",
|
||||
"custom-navbar-activities.min.js": "7CCA4AF4555CF9E9D338FE7285879C9F1396112F1FCD7293AD92EEE965E656C3",
|
||||
"custom-navbar-blank.min.js": "DC2B75D5760EECD3A257785FDFBB7E5DEBF61CD9083C68DD5BCE468B093F54F3",
|
||||
"custom-navbar-category.min.js": "4CF38ACE1D0501217266D1E35DFCBF9D5C1D9A3838C54D53C614878BB8CF55E2",
|
||||
"custom-navbar-component.min.js": "D1B98EDF5C32D19E4A009D2303F69207B35ED35DD06E0F161E7D0BBB313F3C37",
|
||||
"custom-navbar-favorites-list.min.js": "8F4387F2E99B6D25DF5325EAFB158E159217FAFC586EAA3D2C055E862DB459A7",
|
||||
"custom-navbar-iframe.min.js": "C4EE469EC09655F9FF535ACBBD2A5F7C332DA2081936F8F485F5FB015EBD794B",
|
||||
"custom-navbar-logo.min.js": "236CCC887A3917A6D4840889B7380B648197765B8CDA27CB233F3F1E3215F7BB",
|
||||
"custom-navbar-messages.min.js": "D7B315A4D8FD9E2EF9C1E40C1F3CA7EC18C5A87AC7A9410049061A0D851868DE",
|
||||
@ -47,7 +48,7 @@
|
||||
"custom-navbar-upload.min.js": "0CDEEA46DCF0D6187C86BB12DE8CD36737116EF171AA1F63AB20C5DC7549C976",
|
||||
"custom-navbar-user-info.min.js": "F0C8D9FC280BA0A69746EC36079FA97AD9F0B69EB7D8FB56C6ED815C46791321",
|
||||
"custom-navbar-video-list.min.js": "08D6713144E910C1303CB610A5890A5663B92BE82630BDA3C8E6299FB4A429E2",
|
||||
"custom-navbar-watchlater-list.min.js": "CFE0290F6F87551FF04C5D079A63FB7A0680A2706FC9CD9E034F97975703D045",
|
||||
"custom-navbar-watchlater-list.min.js": "2742EAFAA8C716A9E937F70DE1D222DAA97A83EA6323B56DA001F609757240DE",
|
||||
"danmaku-converter.min.js": "FDAB4DB2E3C79730A39CDA7C5FD193693621FED206C6549E9B8F13778080CC12",
|
||||
"dark.min.css": "9C8701C1C5947D7579022E3198CA2C7290C2ACC1D9E84D2BD4133F91C80F27DC",
|
||||
"dark-important.min.css": "8453644F7FC8BB0E9DA401DC161815E2AC198E9B4D7A5A19C29934B672F277B1",
|
||||
@ -66,7 +67,7 @@
|
||||
"download-danmaku.min.js": "87BC2B39D99E029BB602AB2F59A387FC960D5779791524F8C26FBC0278CD8F8E",
|
||||
"download-subtitle.min.js": "4B99A00FEEA40C6D577AC8BD8DFFD34D91B75E150C7848B965D58B0096DF762C",
|
||||
"download-video.min.css": "9B7FFAC852999B11DB62B6467CDBA1AEE53B7F3FA6C592185281542B25AF527A",
|
||||
"download-video.min.html": "D662FBB3C6899E75A52D15C59C53FD6966DA6E4CE463BCEFF0008D5BD3796C7F",
|
||||
"download-video.min.html": "B7EC01DF01DBA78A7B009BDA78865891A974F84A1D72964B7393A07E50D5E5F5",
|
||||
"download-video.min.js": "6A43BC28D28CCB2B047E3E7AAF75314F0DB5B2004F75D1414D282FC3A0129888",
|
||||
"download-video-package.min.js": "B10FF11DE7DFBACEC38F195B8E836511E527215B5E177CB1D223D14F30EB1435",
|
||||
"dpi-img.vue.min.js": "905DD5D8071437FE1C04C3E156E61E594C676BF3928241CC52BCAFAAA0FFA089",
|
||||
@ -196,7 +197,7 @@
|
||||
"tweets.min.css": "9015C1F165C91B9205ABBE4E8A3B5FA83DB1EB4B5CF2442846AF61E44FF178A8",
|
||||
"url-params-clean.min.js": "1B9818B2CF9405C0CC97553594BC8F190C04032D2205CFE6FAD5F93F3F62C0FF",
|
||||
"v-checkbox.vue.min.js": "A23C35D5627009A29FD396A024442A19E37DEE70674BF3CE0FA377D781ED2231",
|
||||
"v-dropdown.vue.min.js": "22D3C9C4FE98D522D5E9F3BC91E0EF3F228A8C36486CC0572A5F7770DC27A20D",
|
||||
"v-dropdown.vue.min.js": "7E9837B89A8275F4CDFE239B06B2DD065C657EC8F9117CC41A854304C1C93B32",
|
||||
"video-card.vue.min.js": "D622CD3A5123F605A46D1CFD80B09A42B4391A6C6C9B60062A247CA3F7B33538",
|
||||
"video-card-info.min.js": "13B755C0EE0CA018AE65251E168BAF3395FEA2EB4FAD6949AADD752F61B8819B",
|
||||
"video-dash.min.js": "E0345C36E793F8C05E5FC83DDAB88751CD6BA28FB0A1AA63BC20FBCE330F037B",
|
||||
|
||||
BIN
min/bundle.zip
BIN
min/bundle.zip
Binary file not shown.
1
min/custom-navbar-favorites-list.min.js
vendored
Normal file
1
min/custom-navbar-favorites-list.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(()=>{return(t,i)=>{const{NavbarComponent:a}=i.import("custom-navbar-component");class e extends a{constructor(){super();this.noPadding=true;this.href=`https://space.bilibili.com/${getUID()}/favlist`;this.html=`收藏`;this.active=document.URL.replace(/\?.*$/,"")===`https://space.bilibili.com/${getUID()}/favlist`;this.popupHtml=`\n<div class="favorites-list loading">\n<div class="loading-tip">\n 加载中...\n</div>\n<div class="content">\n<div class="header">\n<v-dropdown class="list-select" @change="changeList()" :round="true" :items="listNames" :value.sync="selectedListName">\n</v-dropdown>\n<a class="more-info" :href="moreLink" title="查看更多" target="_blank">\n 查看更多\n<i class="mdi mdi-dots-horizontal"></i>\n</a>\n</div>\n<transition-group name="cards" tag="div" class="cards">\n<div class="loading-tip" v-if="cardsLoading" key="loading-tip">\n 加载中...\n</div>\n<div class="empty-tip" v-if="!cardsLoading && cards.length === 0" key="empty-tip">\n 空空如也哦 = ̄ω ̄=\n</div>\n<div class="favorite-card" v-for="card of cards" :key="card.id">\n<a class="cover-container" target="_blank" :href="'https://www.bilibili.com/video/av' + card.aid">\n<dpi-img class="cover" :src="card.coverUrl" :size="{width: 130, height: 85}"></dpi-img>\n<div class="floating duration">{{card.durationText}}</div>\n<div class="floating favorite-time">{{card.favoriteTime | formatDate}}</div>\n</a>\n<a class="title" target="_blank" :href="'https://www.bilibili.com/video/av' + card.aid" :title="card.title">{{card.title}}</a>\n<a class="up" target="_blank" :href="'https://space.bilibili.com/' + card.upID" :title="card.upName">\n<dpi-img class="face" :src="card.upFaceUrl" :size="20"></dpi-img>\n<div class="name">{{card.upName}}</div>\n</a>\n</div>\n</transition-group>\n</div>\n</div>\n`;this.initialPopup=(()=>this.init())}get name(){return"favoritesList"}async init(){new Vue({el:await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .favorites-list`),store:store,filters:{formatDate(t){return`${t.getFullYear()}-${(t.getMonth()+1).toString().padEnd(2,"0")}-${t.getDate().toString().padEnd(2,"0")}`}},components:{DpiImg:()=>i.importAsync("dpi-img.vue"),VDropdown:()=>i.importAsync("v-dropdown.vue")},data:{list:[],cards:[],selectedListName:"",cardsLoading:true},computed:{listNames(){return this.list.map(t=>t.name)},selectedListId(){const t=this.list.find(t=>t.name===this.selectedListName);return t?t.id:0},moreLink(){const t=this.selectedListId;if(t===0){return`https://space.bilibili.com/${getUID()}/favlist`}return`https://space.bilibili.com/${getUID()}/favlist?fid=${t}`}},methods:{async changeList(){try{this.cards=[];this.cardsLoading=true;const t=`https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=${this.selectedListId}&pn=1&ps=20`;const i=await Ajax.getJsonWithCredentials(t);if(i.code!==0){throw new Error(`加载收藏夹内容失败: ${i.message}`)}this.cards=i.data.medias.filter(t=>{return t.attr===0}).map(t=>{return{id:t.id,aid:t.id,coverUrl:t.cover.replace("http:","https:"),favoriteTimestamp:t.fav_time*1e3,favoriteTime:new Date(t.fav_time*1e3),title:t.title,description:t.intro,duration:t.duration,durationText:formatDuration(t.duration),playCount:t.cnt_info.play,danmakuCount:t.cnt_info.danmaku,upName:t.upper.name,upFaceUrl:t.upper.face.replace("http:","https:"),upID:t.upper.mid}})}catch(t){logError(t)}finally{this.cardsLoading=false}}},async mounted(){try{const t=`https://api.bilibili.com/medialist/gateway/base/created?pn=1&ps=100&up_mid=${getUID()}&is_space=0`;const i=await Ajax.getJsonWithCredentials(t);if(i.code!==0){throw new Error(`获取收藏夹列表失败: ${i.message}`)}this.list=i.data.list.map(t=>{return{id:t.id,name:t.title,count:t.media_count}});if(this.list.length>0){this.selectedListName=this.list[0].name;this.changeList()}}catch(t){logError(t)}finally{this.$el.classList.remove("loading")}}})}}return{export:{FavoritesList:e}}}})();
|
||||
2
min/custom-navbar-watchlater-list.min.js
vendored
2
min/custom-navbar-watchlater-list.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(t,i)=>{const{NavbarComponent:a}=i.import("custom-navbar-component");class e extends a{constructor(){super();this.noPadding=true;this.href="https://www.bilibili.com/watchlater/#/list";this.html="稍后再看";this.active=document.URL.startsWith("https://www.bilibili.com/watchlater/");this.popupHtml=`\n<div class="watchlater-list loading">\n<div class="loading-tip">\n 加载中...\n</div>\n<div class="empty-tip" v-if="filteredCards.length === 0">\n 空空如也哦 = ̄ω ̄=\n</div>\n<div class="header">\n \x3c!--<div class="operations">\n<div v-if="!redirect" class="round-button" title="播放全部"><i class="mdi mdi-play-circle-outline"></i></div>\n<div class="round-button" title="移除已观看"><i class="mdi mdi-eye-check-outline"></i></div>\n<div class="round-button" title="清空全部"><i class="mdi mdi-trash-can-outline"></i></div>\n</div>--\x3e\n<div class="search">\n<input type="text" placeholder="搜索" v-model="search">\n</div>\n<a class="more-info" href="https://www.bilibili.com/watchlater/#/list" title="查看更多" target="_blank">\n 查看更多\n<i class="mdi mdi-dots-horizontal"></i>\n</a>\n</div>\n<transition-group name="cards" tag="div" class="cards">\n<div class="watchlater-card" v-for="(card, index) of filteredCards" :key="card.aid">\n<a class="cover-container" target="_blank" :href="card.href">\n<dpi-img class="cover" :src="card.coverUrl" :size="{width: 130, height: 85}"></dpi-img>\n<div class="floating remove" title="移除" @click.prevent="remove(card.aid, index)"><i class="mdi mdi-close"></i></div>\n<div class="floating duration">{{card.durationText}}</div>\n<div class="floating viewed" v-if="card.complete">\n 已观看\n</div>\n</a>\n<a class="title" target="_blank" :href="card.href" :title="card.title">{{card.title}}</a>\n<a class="up" target="_blank" :href="'https://space.bilibili.com/' + card.upID" :title="card.upName">\n<dpi-img class="face" :src="card.upFaceUrl" :size="20"></dpi-img>\n<div class="name">{{card.upName}}</div>\n</a>\n</div>\n</transition-group>\n \x3c!--<div class="undo round-button">\n<i class="mdi mdi-undo-variant"></i>\n 撤销\n</div>--\x3e\n</div>\n`;this.initialPopup=(()=>{this.init()})}async init(){console.log(await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`));new Vue({el:await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`),store:store,components:{DpiImg:()=>i.importAsync("dpi-img.vue")},data:{cards:[],filteredCards:[],search:"",lastRemovedAid:0},computed:{...Vuex.mapState(["watchlaterList"])},watch:{watchlaterList(){this.updateList()},search(){this.updateFilteredCards()}},methods:{...Vuex.mapActions(["toggleWatchlater"]),async updateList(){const{getWatchlaterList:a}=await i.importAsync("watchlater-api");const e=await a(true);if(!e){this.cards=[];return}const s=e.map(i=>{const a=(()=>{if(i.pages===undefined){return t.watchLaterRedirect?`https://www.bilibili.com/video/av${i.aid}`:`https://www.bilibili.com/watchlater/#/av${i.aid}`}const a=i.pages.map(t=>t.cid);const e=i.cid===0?1:a.indexOf(i.cid)+1;return t.watchLaterRedirect?`https://www.bilibili.com/video/av${i.aid}?p=${e}`:`https://www.bilibili.com/watchlater/#/av${i.aid}/p${e}`})();const e=Math.round(1e3*i.progress/i.duration)/1e3;return{aid:i.aid,href:a,coverUrl:i.pic.replace("http:","https:"),durationText:formatDuration(i.duration),duration:i.duration,complete:i.progress<0||e>.95,title:i.title,upName:i.owner.name,upFaceUrl:i.owner.face.replace("http:","https:"),upID:i.owner.mid}});this.cards=s;if(this.search){this.updateFilteredCards()}else{this.filteredCards=s}},async remove(t,i){this.cards.splice(i,1);await this.toggleWatchlater(t);this.lastRemovedAid=t},async undo(){const t=this.lastRemovedAid;if(t!==0){await this.toggleWatchlater(t)}},updateFilteredCards:_.debounce(function(){const t=this.search.toLowerCase();const i=this.$el.querySelector(".cards");i.scrollTo(0,0);this.filteredCards=this.cards.filter(i=>{return i.title.toLowerCase().includes(t)||i.upName.toLowerCase().includes(t)})},200)},async mounted(){try{await this.updateList()}finally{this.$el.classList.remove("loading")}}})}get name(){return"watchlaterList"}}return{export:{WatchlaterList:e}}}})();
|
||||
(()=>{return(t,i)=>{const{NavbarComponent:a}=i.import("custom-navbar-component");class e extends a{constructor(){super();this.noPadding=true;this.href="https://www.bilibili.com/watchlater/#/list";this.html="稍后再看";this.active=document.URL.startsWith("https://www.bilibili.com/watchlater/");this.popupHtml=`\n<div class="watchlater-list loading">\n<div class="loading-tip">\n 加载中...\n</div>\n<div class="empty-tip" v-if="filteredCards.length === 0">\n 空空如也哦 = ̄ω ̄=\n</div>\n<div class="header">\n \x3c!--<div class="operations">\n<div v-if="!redirect" class="round-button" title="播放全部"><i class="mdi mdi-play-circle-outline"></i></div>\n<div class="round-button" title="移除已观看"><i class="mdi mdi-eye-check-outline"></i></div>\n<div class="round-button" title="清空全部"><i class="mdi mdi-trash-can-outline"></i></div>\n</div>--\x3e\n<div class="search">\n<input type="text" placeholder="搜索" v-model="search">\n</div>\n<a class="more-info" href="https://www.bilibili.com/watchlater/#/list" title="查看更多" target="_blank">\n 查看更多\n<i class="mdi mdi-dots-horizontal"></i>\n</a>\n</div>\n<transition-group name="cards" tag="div" class="cards">\n<div class="watchlater-card" v-for="(card, index) of filteredCards" :key="card.aid">\n<a class="cover-container" target="_blank" :href="card.href">\n<dpi-img class="cover" :src="card.coverUrl" :size="{width: 130, height: 85}"></dpi-img>\n<div class="floating remove" title="移除" @click.prevent="remove(card.aid, index)"><i class="mdi mdi-close"></i></div>\n<div class="floating duration">{{card.durationText}}</div>\n<div class="floating viewed" v-if="card.complete">\n 已观看\n</div>\n</a>\n<a class="title" target="_blank" :href="card.href" :title="card.title">{{card.title}}</a>\n<a class="up" target="_blank" :href="'https://space.bilibili.com/' + card.upID" :title="card.upName">\n<dpi-img class="face" :src="card.upFaceUrl" :size="20"></dpi-img>\n<div class="name">{{card.upName}}</div>\n</a>\n</div>\n</transition-group>\n \x3c!--<div class="undo round-button">\n<i class="mdi mdi-undo-variant"></i>\n 撤销\n</div>--\x3e\n</div>\n`;this.initialPopup=(()=>{this.init()})}async init(){new Vue({el:await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`),store:store,components:{DpiImg:()=>i.importAsync("dpi-img.vue")},data:{cards:[],filteredCards:[],search:"",lastRemovedAid:0},computed:{...Vuex.mapState(["watchlaterList"])},watch:{watchlaterList(){this.updateList()},search(){this.updateFilteredCards()}},methods:{...Vuex.mapActions(["toggleWatchlater"]),async updateList(){const{getWatchlaterList:a}=await i.importAsync("watchlater-api");const e=await a(true);if(!e){this.cards=[];return}const s=e.map(i=>{const a=(()=>{if(i.pages===undefined){return t.watchLaterRedirect?`https://www.bilibili.com/video/av${i.aid}`:`https://www.bilibili.com/watchlater/#/av${i.aid}`}const a=i.pages.map(t=>t.cid);const e=i.cid===0?1:a.indexOf(i.cid)+1;return t.watchLaterRedirect?`https://www.bilibili.com/video/av${i.aid}?p=${e}`:`https://www.bilibili.com/watchlater/#/av${i.aid}/p${e}`})();const e=Math.round(1e3*i.progress/i.duration)/1e3;return{aid:i.aid,href:a,coverUrl:i.pic.replace("http:","https:"),durationText:formatDuration(i.duration),duration:i.duration,complete:i.progress<0||e>.95,title:i.title,upName:i.owner.name,upFaceUrl:i.owner.face.replace("http:","https:"),upID:i.owner.mid}});this.cards=s;if(this.search){this.updateFilteredCards()}else{this.filteredCards=s}},async remove(t,i){this.cards.splice(i,1);await this.toggleWatchlater(t);this.lastRemovedAid=t},async undo(){const t=this.lastRemovedAid;if(t!==0){await this.toggleWatchlater(t)}},updateFilteredCards:_.debounce(function(){const t=this.search.toLowerCase();const i=this.$el.querySelector(".cards");i.scrollTo(0,0);this.filteredCards=this.cards.filter(i=>{return i.title.toLowerCase().includes(t)||i.upName.toLowerCase().includes(t)})},200)},async mounted(){try{await this.updateList()}finally{this.$el.classList.remove("loading")}}})}get name(){return"watchlaterList"}}return{export:{WatchlaterList:e}}}})();
|
||||
2
min/custom-navbar.min.css
vendored
2
min/custom-navbar.min.css
vendored
File diff suppressed because one or more lines are too long
2
min/custom-navbar.min.js
vendored
2
min/custom-navbar.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(t,i)=>{const a=["//www.bilibili.com","//t.bilibili.com","//search.bilibili.com","//space.bilibili.com","//account.bilibili.com","//pay.bilibili.com","//member.bilibili.com","//big.bilibili.com","//message.bilibili.com","//app.bilibili.com","//passport.bilibili.com","//game.bilibili.com","//live.bilibili.com/blackboard/"];const s=["//t.bilibili.com/vote/h5/index/#/result","//t.bilibili.com/lottery/h5/index/#/result","//member.bilibili.com/video/upload","//space.bilibili.com/ajax/","//www.bilibili.com/h5/comment/","//www.bilibili.com/blackboard/"];const o=()=>{document.body.style.setProperty("--navbar-bounds-padding",`0 ${t.customNavbarBoundsPadding}%`);document.body.style.setProperty("--navbar-blur-opacity",(t.customNavbarBlurOpacity||.7).toString());addSettingsListener("customNavbarBlurOpacity",t=>{document.body.style.setProperty("--navbar-blur-opacity",t)})};const n=(t,i,a)=>{a.classList.toggle(t,i)};const e=t=>{dq(".custom-navbar").classList.toggle("dark",t);dq(".custom-navbar-settings").classList.toggle("dark",t)};return(()=>{if(isIframe()){return}o();const c=!(!a.some(t=>document.URL.includes(t))||s.some(t=>document.URL.includes(t)))||document.URL.includes("//www.bilibili.com/blackboard/bnj2020.html");if(c){document.body.classList.add("custom-navbar-loading");(async()=>{const a=await i.importAsync("customNavbarHtml");document.body.insertAdjacentHTML("beforeend",a);addSettingsListener("useDarkStyle",e,true);const s=()=>dq(".custom-navbar");["Fill","Shadow","Compact","Blur"].forEach(t=>{const i="customNavbar"+t;addSettingsListener(i,i=>n(t.toLowerCase(),i,s()),true)});SpinQuery.condition(()=>dq("#banner_link,.international-header .bili-banner"),t=>t===null?false:Boolean(t.style.backgroundImage),i=>{Observer.attributes(i,()=>{const a=dqa(".custom-navbar .blur-layer");a.forEach(t=>{t.style.backgroundImage=i.style.backgroundImage;t.setAttribute("data-image",i.style.backgroundImage)});addSettingsListener("customNavbarTransparent",i=>{if(!t.hideBanner){s().classList.toggle("transparent",i)}},true);addSettingsListener("hideBanner",i=>{if(t.customNavbarTransparent){s().classList.toggle("transparent",!i)}})})});const{Blank:o}=await i.importAsync("custom-navbar-blank");const{Logo:c}=await i.importAsync("custom-navbar-logo");const{Category:r}=await i.importAsync("custom-navbar-category");const{SimpleLink:l}=await i.importAsync("custom-navbar-simple-link");const{UserInfo:b}=await i.importAsync("custom-navbar-user-info");const{SearchBox:m}=await i.importAsync("custom-navbar-search-box");const{Iframe:u}=await i.importAsync("custom-navbar-iframe");const d=[new o(1),new c,new r,new l("排行","https://www.bilibili.com/ranking","ranking"),new l("相簿","https://h.bilibili.com","drawing"),new l("音频","https://www.bilibili.com/audio/home/","music"),new u("游戏中心","https://game.bilibili.com/",{src:`https://www.bilibili.com/page-proxy/game-nav.html`,width:`680px`,height:`260px`,lazy:true,iframeName:"games"}),new u("直播","https://live.bilibili.com",{src:`https://live.bilibili.com/blackboard/dropdown-menu.html`,width:`528px`,height:`266px`,lazy:true,iframeName:"lives"}),new l("会员购","https://show.bilibili.com","shop"),new l("漫画","https://manga.bilibili.com","manga"),new o(2),new m,new b];if(getUID()){const{WatchlaterList:t}=await i.importAsync("custom-navbar-watchlater-list");const{Messages:a}=await i.importAsync("custom-navbar-messages");const{Activities:s}=await i.importAsync("custom-navbar-activities");const{Subscriptions:o}=await i.importAsync("custom-navbar-subscriptions");const{FavoritesList:n,HistoryList:e}=await i.importAsync("custom-navbar-video-list");d.push(new a,new o,new s,new t,new n,new e)}const{Upload:p}=await i.importAsync("custom-navbar-upload");d.push(new p,new o(3));new Vue({el:".custom-navbar",data:{components:d},methods:{requestPopup(t){if(!t.requestedPopup&&!t.disabled&&!t.active){this.$set(t,`requestedPopup`,true);t.initialPopup&&t.initialPopup()}t.onPopup&&t.onPopup()}},mounted(){document.body.classList.remove("custom-navbar-loading")}})})()}return{widget:{content:`\n<div class="gui-settings-flat-button" id="custom-navbar-settings">\n<i class="mdi mdi-24px mdi-auto-fix"></i>\n<span>顶栏布局</span>\n</div>`,condition:()=>c,success:async()=>{const{initSettingsPanel:t}=await i.importAsync("custom-navbar-settings");await t()}},unload:()=>{const t=dqa(".custom-navbar,.custom-navbar-settings");t.forEach(t=>t.style.display="none");i.removeStyle("customNavbarStyle")},reload:()=>{const t=dqa(".custom-navbar,.custom-navbar-settings");t.forEach(t=>t.style.display="flex");i.applyImportantStyle("customNavbarStyle")}}})()}})();
|
||||
(()=>{return(t,i)=>{const a=["//www.bilibili.com","//t.bilibili.com","//search.bilibili.com","//space.bilibili.com","//account.bilibili.com","//pay.bilibili.com","//member.bilibili.com","//big.bilibili.com","//message.bilibili.com","//app.bilibili.com","//passport.bilibili.com","//game.bilibili.com","//live.bilibili.com/blackboard/"];const s=["//t.bilibili.com/vote/h5/index/#/result","//t.bilibili.com/lottery/h5/index/#/result","//member.bilibili.com/video/upload","//space.bilibili.com/ajax/","//www.bilibili.com/h5/comment/","//www.bilibili.com/blackboard/"];const o=()=>{document.body.style.setProperty("--navbar-bounds-padding",`0 ${t.customNavbarBoundsPadding}%`);document.body.style.setProperty("--navbar-blur-opacity",(t.customNavbarBlurOpacity||.7).toString());addSettingsListener("customNavbarBlurOpacity",t=>{document.body.style.setProperty("--navbar-blur-opacity",t)})};const n=(t,i,a)=>{a.classList.toggle(t,i)};const e=t=>{dq(".custom-navbar").classList.toggle("dark",t);dq(".custom-navbar-settings").classList.toggle("dark",t)};return(()=>{if(isIframe()){return}o();const c=!(!a.some(t=>document.URL.includes(t))||s.some(t=>document.URL.includes(t)))||document.URL.includes("//www.bilibili.com/blackboard/bnj2020.html");if(c){document.body.classList.add("custom-navbar-loading");(async()=>{const a=await i.importAsync((()=>"customNavbarHtml")());document.body.insertAdjacentHTML("beforeend",a);addSettingsListener("useDarkStyle",e,true);const s=()=>dq(".custom-navbar");["Fill","Shadow","Compact","Blur"].forEach(t=>{const i="customNavbar"+t;addSettingsListener(i,i=>n(t.toLowerCase(),i,s()),true)});SpinQuery.condition(()=>dq("#banner_link,.international-header .bili-banner"),t=>t===null?false:Boolean(t.style.backgroundImage),i=>{Observer.attributes(i,()=>{const a=dqa(".custom-navbar .blur-layer");a.forEach(t=>{t.style.backgroundImage=i.style.backgroundImage;t.setAttribute("data-image",i.style.backgroundImage)});addSettingsListener("customNavbarTransparent",i=>{if(!t.hideBanner){s().classList.toggle("transparent",i)}},true);addSettingsListener("hideBanner",i=>{if(t.customNavbarTransparent){s().classList.toggle("transparent",!i)}})})});const{Blank:o}=await i.importAsync("custom-navbar-blank");const{Logo:c}=await i.importAsync("custom-navbar-logo");const{Category:r}=await i.importAsync("custom-navbar-category");const{SimpleLink:l}=await i.importAsync("custom-navbar-simple-link");const{UserInfo:m}=await i.importAsync("custom-navbar-user-info");const{SearchBox:b}=await i.importAsync("custom-navbar-search-box");const{Iframe:u}=await i.importAsync("custom-navbar-iframe");const d=[new o(1),new c,new r,new l("排行","https://www.bilibili.com/ranking","ranking"),new l("相簿","https://h.bilibili.com","drawing"),new l("音频","https://www.bilibili.com/audio/home/","music"),new u("游戏中心","https://game.bilibili.com/",{src:`https://www.bilibili.com/page-proxy/game-nav.html`,width:`680px`,height:`260px`,lazy:true,iframeName:"games"}),new u("直播","https://live.bilibili.com",{src:`https://live.bilibili.com/blackboard/dropdown-menu.html`,width:`528px`,height:`266px`,lazy:true,iframeName:"lives"}),new l("会员购","https://show.bilibili.com","shop"),new l("漫画","https://manga.bilibili.com","manga"),new o(2),new b,new m];if(getUID()){const{WatchlaterList:t}=await i.importAsync("custom-navbar-watchlater-list");const{Messages:a}=await i.importAsync("custom-navbar-messages");const{Activities:s}=await i.importAsync("custom-navbar-activities");const{Subscriptions:o}=await i.importAsync("custom-navbar-subscriptions");const{FavoritesList:n}=await i.importAsync("custom-navbar-favorites-list");const{HistoryList:e}=await i.importAsync("custom-navbar-video-list");d.push(new a,new o,new s,new t,new n,new e)}const{Upload:p}=await i.importAsync("custom-navbar-upload");d.push(new p,new o(3));new Vue({el:".custom-navbar",data:{components:d},methods:{requestPopup(t){if(!t.requestedPopup&&!t.disabled&&!t.active){this.$set(t,`requestedPopup`,true);t.initialPopup&&t.initialPopup()}t.onPopup&&t.onPopup()}},mounted(){document.body.classList.remove("custom-navbar-loading")}})})()}return{widget:{content:`\n<div class="gui-settings-flat-button" id="custom-navbar-settings">\n<i class="mdi mdi-24px mdi-auto-fix"></i>\n<span>顶栏布局</span>\n</div>`,condition:()=>c,success:async()=>{const{initSettingsPanel:t}=await i.importAsync("custom-navbar-settings");await t()}},unload:()=>{const t=dqa(".custom-navbar,.custom-navbar-settings");t.forEach(t=>t.style.display="none");i.removeStyle("customNavbarStyle")},reload:()=>{const t=dqa(".custom-navbar,.custom-navbar-settings");t.forEach(t=>t.style.display="flex");i.applyImportantStyle("customNavbarStyle")}}})()}})();
|
||||
File diff suppressed because one or more lines are too long
2
min/v-dropdown.vue.min.js
vendored
2
min/v-dropdown.vue.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(o,e)=>{const n=`<div class=v-dropdown @click=toggleDropdown()><span class=selected>{{ value }}</span><ul class=dropdown-menu :class="{ opened: dropdownOpen }"><li v-for="item in items":key=item :data-value=item @click=select(item)>{{ item }}</li></ul><i class="mdi mdi-chevron-down"></i></div>`;e.applyStyleFromText(`.v-dropdown{--background-color:#eee;position:relative;background-color:var(--background-color);cursor:pointer;display:flex;align-items:center;justify-content:space-between;min-width:100px}body.dark .v-dropdown{--background-color:#333}.v-dropdown .dropdown-menu{transform-origin:top;transform:translateY(-4px) translateX(-50%);pointer-events:none;opacity:0;position:absolute;top:calc(100% + 2px);left:50%;background-color:var(--background-color);z-index:1;transition:.2s ease-out;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0}.v-dropdown .dropdown-menu.opened{transform:translateY(0) translateX(-50%);pointer-events:initial;opacity:1}.v-dropdown .dropdown-menu li{padding:4px 16px;box-sizing:content-box;white-space:nowrap;min-width:64px;text-align:center;cursor:pointer;color:inherit;background-color:transparent}.v-dropdown .dropdown-menu li:hover{background-color:rgba(0,0,0,.16)}.v-dropdown .mdi-chevron-down{font-size:16pt;line-height:1;transform:rotate(0)}.v-dropdown .dropdown-menu.opened~.mdi-chevron-down{transform:rotate(180deg)}.v-dropdown .selected{user-select:none;padding:4px 8px}.round-corner .v-dropdown,.round-corner .v-dropdown .dropdown-menu,.round-corner .v-dropdown .dropdown-menu li{border-radius:var(--corner-radius)}`,"v-dropdown-style");return{export:Object.assign({template:n},{props:["items","value"],data(){return{dropdownOpen:false}},methods:{toggleDropdown(){this.dropdownOpen=!this.dropdownOpen;if(this.dropdownOpen){document.addEventListener("click",o=>{const e=o.target;if(e===this.$el||this.$el.contains(e)){return}this.dropdownOpen=false},{once:true,capture:true})}},select(o){this.$emit("update:value",o);this.$emit("change",o)}}})}}})();
|
||||
(()=>{return(o,e)=>{const r=`<div class=v-dropdown @click=toggleDropdown() :class={round}><span class=selected>{{ value }}</span><ul class=dropdown-menu :class="{ opened: dropdownOpen }"><li v-for="item in items":key=item :data-value=item @click=select(item)>{{ item }}</li></ul><i class="mdi mdi-chevron-down"></i></div>`;e.applyStyleFromText(`.v-dropdown{--background-color:#eee;position:relative;background-color:var(--background-color);cursor:pointer;display:flex;align-items:center;justify-content:space-between;min-width:100px;border-radius:var(--corner-radius)}body.dark .v-dropdown{--background-color:#333}.v-dropdown.round{border-radius:14px;padding:0 4px}.v-dropdown .dropdown-menu{transform-origin:top;transform:translateY(-4px) translateX(-50%);pointer-events:none;opacity:0;position:absolute;top:calc(100% + 2px);left:50%;background-color:var(--background-color);z-index:1;transition:.2s ease-out;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;border-radius:var(--corner-radius)}.v-dropdown .dropdown-menu.opened{transform:translateY(0) translateX(-50%);pointer-events:initial;opacity:1}.v-dropdown .dropdown-menu li{padding:4px 16px;box-sizing:content-box;white-space:nowrap;min-width:64px;text-align:center;cursor:pointer;color:inherit;background-color:transparent;border-radius:var(--corner-radius)}.v-dropdown .dropdown-menu li:hover{background-color:rgba(0,0,0,.16)}.v-dropdown .mdi-chevron-down{font-size:16pt;line-height:1;transform:rotate(0)}.v-dropdown .dropdown-menu.opened~.mdi-chevron-down{transform:rotate(180deg)}.v-dropdown .selected{user-select:none;padding:4px 8px}`,"v-dropdown-style");return{export:Object.assign({template:r},{props:["items","value","round"],data(){return{dropdownOpen:false}},methods:{toggleDropdown(){this.dropdownOpen=!this.dropdownOpen;if(this.dropdownOpen){document.addEventListener("click",o=>{const e=o.target;if(e===this.$el||this.$el.contains(e)){return}this.dropdownOpen=false},{once:true,capture:true})}},select(o){if(o!==this.value){this.$emit("update:value",o);this.$emit("change",o)}}}})}}})();
|
||||
30
src/style/_common.scss
Normal file
30
src/style/_common.scss
Normal file
@ -0,0 +1,30 @@
|
||||
@mixin h-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@mixin v-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
@mixin h-stretch {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
@mixin v-stretch {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
@mixin round-bar($height) {
|
||||
box-sizing: border-box;
|
||||
height: #{$height}px;
|
||||
border-radius: #{$height / 2}px;
|
||||
}
|
||||
@mixin no-scrollbar {
|
||||
scrollbar-width: none !important;
|
||||
&::-webkit-scrollbar {
|
||||
height: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
}
|
||||
@ -851,7 +851,7 @@ li.nav-item[report-id="playpage_dynamic"] .i-frame,
|
||||
}
|
||||
}
|
||||
@import "./activities/activities", "./subscriptions/subscriptions", "_round-corner", "./settings/settings",
|
||||
"./category/category", "./watchlater-list/watchlater-list";
|
||||
"./category/category", "./watchlater-list/watchlater-list", "./favorites-list/favorites-list";
|
||||
|
||||
.custom-navbar > ul > li:not(.disabled):hover > .popup,
|
||||
#custom-navbar-home-popup .category-item:hover .popup,
|
||||
|
||||
@ -119,7 +119,8 @@ export default (() => {
|
||||
const { Messages } = await import('./simple/custom-navbar-messages')
|
||||
const { Activities } = await import('./activities/custom-navbar-activities')
|
||||
const { Subscriptions } = await import('./subscriptions/custom-navbar-subscriptions')
|
||||
const { FavoritesList, HistoryList } = await import('./simple/custom-navbar-video-list')
|
||||
const { FavoritesList } = await import('./favorites-list/custom-navbar-favorites-list')
|
||||
const { HistoryList } = await import('./simple/custom-navbar-video-list')
|
||||
components.push(
|
||||
new Messages(),
|
||||
new Subscriptions(),
|
||||
|
||||
179
src/style/custom-navbar/favorites-list/_favorites-list.scss
Normal file
179
src/style/custom-navbar/favorites-list/_favorites-list.scss
Normal file
@ -0,0 +1,179 @@
|
||||
@import "../../common";
|
||||
.custom-navbar .favorites-list {
|
||||
width: 380px;
|
||||
height: 600px;
|
||||
font-size: 12px;
|
||||
@include v-stretch();
|
||||
justify-content: center;
|
||||
.empty-tip,
|
||||
.loading-tip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
& > .loading-tip {
|
||||
display: none;
|
||||
}
|
||||
.mdi {
|
||||
line-height: 1;
|
||||
font-size: 18px;
|
||||
}
|
||||
&.loading {
|
||||
& > .loading-tip {
|
||||
display: flex;
|
||||
}
|
||||
& > :not(.loading-tip) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
@include v-stretch();
|
||||
@include no-scrollbar();
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
overflow: auto;
|
||||
.floating {
|
||||
@include round-bar(20);
|
||||
@include h-center();
|
||||
background-color: #000c;
|
||||
color: white;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.header {
|
||||
@include h-center();
|
||||
justify-content: space-between;
|
||||
margin: 16px 12px;
|
||||
.list-select {
|
||||
height: 26px;
|
||||
}
|
||||
.more-info {
|
||||
@include h-center();
|
||||
@include round-bar(26);
|
||||
padding: 4px 6px 4px 10px;
|
||||
background-color: #8882;
|
||||
&:hover {
|
||||
background-color: #8884;
|
||||
}
|
||||
.mdi {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cards {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
scroll-behavior: smooth;
|
||||
position: relative;
|
||||
@include no-scrollbar();
|
||||
margin: 0 12px;
|
||||
padding-bottom: 12px;
|
||||
&-enter,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-16px) scale(0.9);
|
||||
}
|
||||
&-leave-active {
|
||||
transition: 0.24s cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
position: absolute;
|
||||
}
|
||||
.favorite-card {
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px 0 #0001;
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
display: grid;
|
||||
grid-template:
|
||||
"cover title" 2fr
|
||||
"cover info" 1fr / 130px 1fr;
|
||||
height: 85px;
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.cover-container {
|
||||
grid-area: cover;
|
||||
overflow: hidden;
|
||||
border-radius: 8px 0 0 8px;
|
||||
position: relative;
|
||||
$padding: 6px;
|
||||
.favorite-time{
|
||||
top: $padding;
|
||||
left: $padding;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.duration {
|
||||
left: $padding;
|
||||
bottom: $padding;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.floating {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
.cover {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.floating {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
grid-area: title;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
max-height: 3em;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
overflow: hidden;
|
||||
margin-top: 8px;
|
||||
padding: 0 10px;
|
||||
&:hover {
|
||||
color: var(--theme-color) !important;
|
||||
}
|
||||
}
|
||||
.up {
|
||||
flex: 0 1 auto;
|
||||
padding: 2px 10px 2px 2px;
|
||||
margin: 0 8px 6px;
|
||||
justify-self: start;
|
||||
align-self: center;
|
||||
max-width: calc(100% - 16px);
|
||||
@include h-center();
|
||||
@include round-bar(24);
|
||||
background-color: #8882;
|
||||
&:hover {
|
||||
background-color: #8884;
|
||||
}
|
||||
.face {
|
||||
border-radius: 50%;
|
||||
margin-right: 6px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.name {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 11px;
|
||||
}
|
||||
&:hover .name {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,164 @@
|
||||
import { NavbarComponent } from '../custom-navbar-component'
|
||||
import { VideoCardInfo } from '../../simplify-home/video-card-info'
|
||||
interface ListInfo {
|
||||
id: number
|
||||
name: string
|
||||
count: number
|
||||
}
|
||||
interface FavoritesItemInfo extends VideoCardInfo {
|
||||
favoriteTimestamp: number
|
||||
favoriteTime: Date
|
||||
}
|
||||
export class FavoritesList extends NavbarComponent {
|
||||
constructor() {
|
||||
super()
|
||||
this.noPadding = true
|
||||
this.href = `https://space.bilibili.com/${getUID()}/favlist`
|
||||
this.html = `收藏`
|
||||
this.active = document.URL.replace(/\?.*$/, "") === `https://space.bilibili.com/${getUID()}/favlist`
|
||||
this.popupHtml = /*html*/`
|
||||
<div class="favorites-list loading">
|
||||
<div class="loading-tip">
|
||||
加载中...
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
<v-dropdown class="list-select" @change="changeList()" :round="true" :items="listNames" :value.sync="selectedListName">
|
||||
</v-dropdown>
|
||||
<a class="more-info" :href="moreLink" title="查看更多" target="_blank">
|
||||
查看更多
|
||||
<i class="mdi mdi-dots-horizontal"></i>
|
||||
</a>
|
||||
</div>
|
||||
<transition-group name="cards" tag="div" class="cards">
|
||||
<div class="loading-tip" v-if="cardsLoading" key="loading-tip">
|
||||
加载中...
|
||||
</div>
|
||||
<div class="empty-tip" v-if="!cardsLoading && cards.length === 0" key="empty-tip">
|
||||
空空如也哦 = ̄ω ̄=
|
||||
</div>
|
||||
<div class="favorite-card" v-for="card of cards" :key="card.id">
|
||||
<a class="cover-container" target="_blank" :href="'https://www.bilibili.com/video/av' + card.aid">
|
||||
<dpi-img class="cover" :src="card.coverUrl" :size="{width: 130, height: 85}"></dpi-img>
|
||||
<div class="floating duration">{{card.durationText}}</div>
|
||||
<div class="floating favorite-time">{{card.favoriteTime | formatDate}}</div>
|
||||
</a>
|
||||
<a class="title" target="_blank" :href="'https://www.bilibili.com/video/av' + card.aid" :title="card.title">{{card.title}}</a>
|
||||
<a class="up" target="_blank" :href="'https://space.bilibili.com/' + card.upID" :title="card.upName">
|
||||
<dpi-img class="face" :src="card.upFaceUrl" :size="20"></dpi-img>
|
||||
<div class="name">{{card.upName}}</div>
|
||||
</a>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
this.initialPopup = () => this.init()
|
||||
}
|
||||
get name(): keyof CustomNavbarOrders {
|
||||
return 'favoritesList'
|
||||
}
|
||||
async init() {
|
||||
new Vue({
|
||||
el: await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .favorites-list`) as HTMLElement,
|
||||
store,
|
||||
filters: {
|
||||
formatDate(value: Date) {
|
||||
return `${value.getFullYear()}-${(value.getMonth() + 1).toString().padEnd(2, '0')}-${(value.getDate()).toString().padEnd(2, '0')}`
|
||||
}
|
||||
},
|
||||
components: {
|
||||
DpiImg: () => import('../dpi-img.vue'),
|
||||
VDropdown: () => import('../../../video/download-video/v-dropdown.vue'),
|
||||
},
|
||||
data: {
|
||||
list: [],
|
||||
cards: [],
|
||||
selectedListName: '',
|
||||
cardsLoading: true,
|
||||
},
|
||||
computed: {
|
||||
listNames() {
|
||||
return this.list.map((item: ListInfo) => item.name)
|
||||
},
|
||||
selectedListId() {
|
||||
const item = (this.list as ListInfo[]).find(item => item.name === this.selectedListName)!
|
||||
return item ? item.id : 0
|
||||
},
|
||||
moreLink() {
|
||||
const id = this.selectedListId
|
||||
if (id === 0) {
|
||||
return `https://space.bilibili.com/${getUID()}/favlist`
|
||||
}
|
||||
return `https://space.bilibili.com/${getUID()}/favlist?fid=${id}`
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async changeList() {
|
||||
try {
|
||||
this.cards = []
|
||||
this.cardsLoading = true
|
||||
const url = `https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=${this.selectedListId}&pn=1&ps=20`
|
||||
const json = await Ajax.getJsonWithCredentials(url)
|
||||
if (json.code !== 0) {
|
||||
throw new Error(`加载收藏夹内容失败: ${json.message}`)
|
||||
}
|
||||
this.cards = json.data.medias.filter((item: any) => {
|
||||
return item.attr === 0 // 过滤掉已失效视频
|
||||
}).map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
aid: item.id,
|
||||
coverUrl: item.cover.replace('http:', 'https:'),
|
||||
favoriteTimestamp: item.fav_time * 1000,
|
||||
favoriteTime: new Date(item.fav_time * 1000),
|
||||
title: item.title,
|
||||
description: item.intro,
|
||||
duration: item.duration,
|
||||
durationText: formatDuration(item.duration),
|
||||
playCount: item.cnt_info.play,
|
||||
danmakuCount: item.cnt_info.danmaku,
|
||||
upName: item.upper.name,
|
||||
upFaceUrl: item.upper.face.replace('http:', 'https:'),
|
||||
upID: item.upper.mid,
|
||||
} as FavoritesItemInfo
|
||||
})
|
||||
} catch (error) {
|
||||
logError(error)
|
||||
} finally {
|
||||
this.cardsLoading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
const url = `https://api.bilibili.com/medialist/gateway/base/created?pn=1&ps=100&up_mid=${getUID()}&is_space=0`
|
||||
const json = await Ajax.getJsonWithCredentials(url)
|
||||
if (json.code !== 0) {
|
||||
throw new Error(`获取收藏夹列表失败: ${json.message}`)
|
||||
}
|
||||
this.list = json.data.list.map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.title,
|
||||
count: item.media_count
|
||||
} as ListInfo
|
||||
})
|
||||
if (this.list.length > 0) {
|
||||
this.selectedListName = this.list[0].name
|
||||
this.changeList()
|
||||
}
|
||||
} catch (error) {
|
||||
logError(error)
|
||||
} finally {
|
||||
this.$el.classList.remove('loading')
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
export default {
|
||||
export: {
|
||||
FavoritesList,
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,5 @@
|
||||
@import "../../common";
|
||||
.custom-navbar {
|
||||
@mixin h-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@mixin round-bar($height) {
|
||||
box-sizing: border-box;
|
||||
height: #{$height}px;
|
||||
border-radius: #{$height / 2}px;
|
||||
}
|
||||
@mixin no-scrollbar {
|
||||
scrollbar-width: none !important;
|
||||
&::-webkit-scrollbar {
|
||||
height: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
}
|
||||
@mixin button-background {
|
||||
background-color: #8882;
|
||||
&:hover {
|
||||
@ -136,8 +121,6 @@
|
||||
scroll-behavior: smooth;
|
||||
position: relative;
|
||||
@include no-scrollbar();
|
||||
// display: flex;
|
||||
// flex-flow: column nowrap;
|
||||
margin: 0 12px;
|
||||
padding-bottom: 12px;
|
||||
&-enter,
|
||||
|
||||
@ -68,7 +68,7 @@ export class WatchlaterList extends NavbarComponent {
|
||||
}
|
||||
}
|
||||
async init() {
|
||||
console.log(await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`))
|
||||
// console.log(await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`))
|
||||
new Vue({
|
||||
el: await SpinQuery.select(`.custom-navbar [data-name="${this.name}"] .watchlater-list`) as HTMLElement,
|
||||
store,
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
<div class="download-video">
|
||||
<a v-bind:href="blobUrl" id="video-complete" style="display: none"></a>
|
||||
<a :href="blobUrl" id="video-complete" style="display: none"></a>
|
||||
<div class="header">
|
||||
<i class="mdi mdi-download"></i>
|
||||
<h1>下载视频</h1>
|
||||
<div class="grow"></div>
|
||||
<i class="mdi mdi-close" v-on:click="close()"></i>
|
||||
<i class="mdi mdi-close" @click="close()"></i>
|
||||
</div>
|
||||
<div v-if="batch" class="tabs">
|
||||
<div class="tab download-single" v-bind:class="{active: downloadSingle}" v-on:click="downloadSingle = true">单个视频
|
||||
<div class="tab download-single" :class="{active: downloadSingle}" @click="downloadSingle = true">单个视频
|
||||
</div>
|
||||
<div class="tab download-batch" v-bind:class="{active: !downloadSingle}" v-on:click="downloadSingle = false">批量导出
|
||||
<div class="tab download-batch" :class="{active: !downloadSingle}" @click="downloadSingle = false">批量导出
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="downloadSingle" class="info">
|
||||
<img v-bind:src="coverUrl" class="cover">
|
||||
<img :src="coverUrl" class="cover">
|
||||
<div class="title">
|
||||
<!-- <span class="bold" v-bind:title="'av' + aid + ' / cid' + cid">av{{aid}} / cid{{cid}}</span> -->
|
||||
<!-- <span class="bold" :title="'av' + aid + ' / cid' + cid">av{{aid}} / cid{{cid}}</span> -->
|
||||
<span class="size">
|
||||
<div v-if="sizeWarning" class="size-warning">
|
||||
<i class="mdi mdi-alert-circle"></i>
|
||||
@ -31,27 +31,29 @@
|
||||
<div class="options">
|
||||
<div class="option-item" v-if="enableDash">
|
||||
格式
|
||||
<v-dropdown style="text-transform: uppercase;" v-on:change="dashChange()" v-bind:items="dashModel.items"
|
||||
v-bind:value.sync="dashModel.value">
|
||||
<v-dropdown style="text-transform: uppercase;" @change="dashChange()" :items="dashModel.items"
|
||||
:value.sync="dashModel.value">
|
||||
</v-dropdown>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
清晰度
|
||||
<v-dropdown v-on:change="formatChange(true)" v-bind:items="qualityModel.items" v-bind:value.sync="qualityModel.value"></v-dropdown>
|
||||
<v-dropdown @change="formatChange(true)" :items="qualityModel.items" :value.sync="qualityModel.value">
|
||||
</v-dropdown>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
弹幕
|
||||
<v-dropdown v-on:change="danmakuOptionChange()" v-bind:items="danmakuModel.items" v-bind:value.sync="danmakuModel.value"></v-dropdown>
|
||||
<v-dropdown @change="danmakuOptionChange()" :items="danmakuModel.items" :value.sync="danmakuModel.value">
|
||||
</v-dropdown>
|
||||
</div>
|
||||
<div class="option-item" v-if="enableDash && dashModel.value === 'dash'">
|
||||
首选编码
|
||||
<v-dropdown v-on:change="codecChange()" v-bind:items="codecModel.items" v-bind:value.sync="codecModel.value">
|
||||
<v-dropdown @change="codecChange()" :items="codecModel.items" :value.sync="codecModel.value">
|
||||
</v-dropdown>
|
||||
</div>
|
||||
<!-- <div class="option-item" v-if="enableDash">
|
||||
ffmpeg支持
|
||||
<v-dropdown v-on:change="ffmpegChange()" v-bind:items="ffmpegModel.items"
|
||||
v-bind:value.sync="ffmpegModel.value"></v-dropdown>
|
||||
<v-dropdown @change="ffmpegChange()" :items="ffmpegModel.items"
|
||||
:value.sync="ffmpegModel.value"></v-dropdown>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
@ -60,11 +62,11 @@
|
||||
<h2>直接下载</h2>
|
||||
<span class="download-speed">{{speed}}</span>
|
||||
</div>
|
||||
<button v-if="!downloading" class="primary start-download" v-on:click="startDownload()">开始</button>
|
||||
<button v-else class="primary cancel-download" v-on:click="cancelDownload()">取消</button>
|
||||
<button v-if="!downloading" class="primary start-download" @click="startDownload()">开始</button>
|
||||
<button v-else class="primary cancel-download" @click="cancelDownload()">取消</button>
|
||||
<div class="progress">
|
||||
<div class="background">
|
||||
<div class="foreground" v-bind:style="{width: progressPercent + '%'}"></div>
|
||||
<div class="foreground" :style="{width: progressPercent + '%'}"></div>
|
||||
</div>
|
||||
<span class="percent">{{progressPercent}}%</span>
|
||||
</div>
|
||||
@ -72,38 +74,40 @@
|
||||
<div v-show="!downloadSingle" class="batch-download">
|
||||
<div class="episode-header">
|
||||
<h2>选集</h2>
|
||||
<button class="list-tool" title="全选" v-on:click="selectAllEpisodes()">
|
||||
<button class="list-tool" title="全选" @click="selectAllEpisodes()">
|
||||
<i class="mdi mdi-checkbox-multiple-marked-circle"></i>
|
||||
</button>
|
||||
<button class="list-tool" title="全不选" v-on:click="unselectAllEpisodes()">
|
||||
<button class="list-tool" title="全不选" @click="unselectAllEpisodes()">
|
||||
<i class="mdi mdi-checkbox-multiple-blank-circle-outline"></i>
|
||||
</button>
|
||||
<button class="list-tool" title="反选" v-on:click="inverseAllEpisodes()">
|
||||
<button class="list-tool" title="反选" @click="inverseAllEpisodes()">
|
||||
<i class="mdi mdi-circle-slice-4"></i>
|
||||
</button>
|
||||
<span class="selected-count">{{selectedEpisodeCount}}/{{episodeList.length}}</span>
|
||||
</div>
|
||||
<div class="episode-list">
|
||||
<v-checkbox v-for="ep of episodeList" v-bind:key="ep.index" v-bind:title="ep.title" v-bind:checked.sync="ep.checked"></v-checkbox>
|
||||
<v-checkbox v-for="ep of episodeList" :key="ep.index" :title="ep.title" :checked.sync="ep.checked"></v-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
<div class="exports">
|
||||
<h2>导出</h2>
|
||||
<div class="actions" v-bind:class="{busy: busy}">
|
||||
<!-- <button class="copy-link" v-bind:disabled="downloadSingle ? null : 'disabled'" v-on:click="exportData('copyLink')">复制链接</button> -->
|
||||
<button class="show-link" v-bind:disabled="downloadSingle ? null : 'disabled'"
|
||||
v-on:click="exportData('showLink')">显示链接</button>
|
||||
<div class="actions" :class="{busy: busy}">
|
||||
<!-- <button class="copy-link" :disabled="downloadSingle ? null : 'disabled'" @click="exportData('copyLink')">复制链接</button> -->
|
||||
<button class="show-link" :disabled="downloadSingle ? null : 'disabled'"
|
||||
@click="exportData('showLink')">显示链接</button>
|
||||
<!-- <button class="idm-export" disabled title="暂不支持导出IDM, 详见 GitHub issue #149">IDM</button> -->
|
||||
<button class="aria2-file" v-on:click="exportData('aria2')">aria2</button>
|
||||
<button class="ffmpeg-fragments" v-if="!dash" v-on:click="exportData('ffmpegFragments')">ffmpeg - 分段列表</button>
|
||||
<button class="ffmpeg-episodes" v-if="!dash" v-bind:disabled="downloadSingle ? 'disabled' : null" v-on:click="exportData('ffmpegEpisodes')">ffmpeg - 分P列表</button>
|
||||
<!-- <button class="vld-copy" v-on:click="exportData('copyVLD')">复制vld数据</button>
|
||||
<button class="vld-export" v-on:click="exportData('exportVLD')">导出vld数据</button> -->
|
||||
<div class="button aria2-rpc" v-on:click.self="toggleRpcSettings()">
|
||||
<button class="aria2-file" @click="exportData('aria2')">aria2</button>
|
||||
<button class="ffmpeg-fragments" v-if="!dash" @click="exportData('ffmpegFragments')">ffmpeg - 分段列表</button>
|
||||
<button class="ffmpeg-episodes" v-if="!dash" :disabled="downloadSingle ? 'disabled' : null"
|
||||
@click="exportData('ffmpegEpisodes')">ffmpeg - 分P列表</button>
|
||||
<!-- <button class="vld-copy" @click="exportData('copyVLD')">复制vld数据</button>
|
||||
<button class="vld-export" @click="exportData('exportVLD')">导出vld数据</button> -->
|
||||
<div class="button aria2-rpc" @click.self="toggleRpcSettings()">
|
||||
{{showRpcSettings ? '取消' : 'aria2 RPC'}}
|
||||
<i :class="{'mdi-close': showRpcSettings, 'mdi-chevron-right': !showRpcSettings}" class="mdi" v-on:click.self="toggleRpcSettings()"></i>
|
||||
<div class="rpc-settings" v-bind:class="{show: showRpcSettings}">
|
||||
<i :class="{'mdi-close': showRpcSettings, 'mdi-chevron-right': !showRpcSettings}" class="mdi"
|
||||
@click.self="toggleRpcSettings()"></i>
|
||||
<div class="rpc-settings" :class="{show: showRpcSettings}">
|
||||
<h1>aria2 RPC</h1>
|
||||
<rpc-profiles @profile-change="updateProfile"></rpc-profiles>
|
||||
<h2>配置</h2>
|
||||
@ -129,11 +133,11 @@
|
||||
最终路径: {{rpcSettings.baseDir + rpcSettings.dir}}
|
||||
</div>
|
||||
<div class="rpc-settings-item">
|
||||
方法<v-dropdown style="text-transform: uppercase;" v-bind:items="['get', 'post']" v-bind:value.sync="rpcSettings.method">
|
||||
方法<v-dropdown style="text-transform: uppercase;" :items="['get', 'post']" :value.sync="rpcSettings.method">
|
||||
</div>
|
||||
<div class="operations">
|
||||
<div class="primary button" v-on:click="saveRpcSettings();toggleRpcSettings();exportData('aria2RPC')">开始下载</div>
|
||||
<div class="button" v-on:click="saveRpcSettings()">{{saveRpcSettingsText}}</div>
|
||||
<div class="primary button" @click="saveRpcSettings();toggleRpcSettings();exportData('aria2RPC')">开始下载</div>
|
||||
<div class="button" @click="saveRpcSettings()">{{saveRpcSettingsText}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="v-dropdown" @click="toggleDropdown()">
|
||||
<div class="v-dropdown" @click="toggleDropdown()" :class="{round}">
|
||||
<span class="selected">{{ value }}</span>
|
||||
<ul class="dropdown-menu" :class="{ opened: dropdownOpen }">
|
||||
<li v-for="item in items" :key="item" :data-value="item" @click="select(item)">{{ item }}</li>
|
||||
@ -9,7 +9,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
props: ['items', 'value'],
|
||||
props: ['items', 'value', 'round'],
|
||||
data() {
|
||||
return {
|
||||
dropdownOpen: false
|
||||
@ -33,8 +33,10 @@ export default {
|
||||
}
|
||||
},
|
||||
select(item: string) {
|
||||
this.$emit('update:value', item)
|
||||
this.$emit('change', item)
|
||||
if (item !== this.value) {
|
||||
this.$emit('update:value', item)
|
||||
this.$emit('change', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,10 +51,15 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 100px;
|
||||
border-radius: var(--corner-radius);
|
||||
|
||||
body.dark & {
|
||||
--background-color: #333;
|
||||
}
|
||||
&.round {
|
||||
border-radius: 14px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.dropdown-menu {
|
||||
transform-origin: top;
|
||||
transform: translateY(-4px) translateX(-50%);
|
||||
@ -65,6 +72,7 @@ export default {
|
||||
z-index: 1;
|
||||
transition: 0.2s ease-out;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 4px 8px 0px;
|
||||
border-radius: var(--corner-radius);
|
||||
&.opened {
|
||||
transform: translateY(0) translateX(-50%);
|
||||
pointer-events: initial;
|
||||
@ -79,6 +87,7 @@ export default {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
border-radius: var(--corner-radius);
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
@ -96,14 +105,5 @@ export default {
|
||||
user-select: none;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.round-corner & {
|
||||
border-radius: var(--corner-radius);
|
||||
|
||||
.dropdown-menu,
|
||||
.dropdown-menu li {
|
||||
border-radius: var(--corner-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user