From 7c2c593c962f25e37d768b189c76127c38d2c9ee Mon Sep 17 00:00:00 2001 From: oxygenkun Date: Sun, 23 Jun 2024 22:50:23 +0800 Subject: [PATCH 01/29] =?UTF-8?q?=E4=B8=BAaria2=E6=8F=90=E4=BE=9B=E5=8F=AF?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=B0=81=E9=9D=A2=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 优化视频下载组件的结构,现在仅在需要的时候获取assets的blob并下载 2. 扩展视频下载组件的接口,插件可以代理处理assets的下载逻辑 3. 扩展视频封面组件和aria2插件以支持aria2下载封面 --- .../lib/components/utils/view-cover/index.ts | 22 +++++- .../video/download/DownloadVideo.vue | 22 +++--- .../lib/components/video/download/types.ts | 20 +++++- .../video/download/aria2-output/RpcConfig.vue | 11 ++- .../video/download/aria2-output/aria2-rpc.ts | 71 +++++++++++++------ 5 files changed, 109 insertions(+), 37 deletions(-) diff --git a/registry/lib/components/utils/view-cover/index.ts b/registry/lib/components/utils/view-cover/index.ts index b56af3d7c..4c5fef9af 100644 --- a/registry/lib/components/utils/view-cover/index.ts +++ b/registry/lib/components/utils/view-cover/index.ts @@ -1,5 +1,5 @@ import { defineComponentMetadata } from '@/components/define' -import { getBlobByAid } from '@/components/video/video-cover' +import { getVideoCoverUrlByAid, getBlobByAid } from '@/components/video/video-cover' import { PackageEntry } from '@/core/download' import { videoAndBangumiUrls } from '@/core/utils/urls' import { Toast } from '@/core/toast' @@ -55,6 +55,26 @@ export const component = defineComponentMetadata({ toast.message = `获取完成. 成功 ${success.length} 个, 失败 ${fail.length} 个.` return success.map(it => it.value) }, + getUrls: async ( + infos, + instance: { + type: CoverDownloadType + enabled: boolean + }, + ) => { + const { type, enabled } = instance + if (!enabled) { + return [] + } + return Promise.all( + infos.map(async info => { + return { + name: `${info.input.title}.${type}`, + url: await getVideoCoverUrlByAid(info.input.aid), + } + }), + ) + }, component: () => import('./Plugin.vue').then(m => m.default), }) }) diff --git a/registry/lib/components/video/download/DownloadVideo.vue b/registry/lib/components/video/download/DownloadVideo.vue index 61b64505f..25c2b5d7a 100644 --- a/registry/lib/components/video/download/DownloadVideo.vue +++ b/registry/lib/components/video/download/DownloadVideo.vue @@ -332,18 +332,16 @@ export default Vue.extend({ }) } const action = new DownloadVideoAction(videoInfos) - const extraAssets = ( - await Promise.all( - assets.map(a => - a.getAssets( - videoInfos, - this.$refs.assetsOptions.find((c: any) => c.$attrs.name === a.name), - ), - ), - ) - ).flat() - action.extraAssets.push(...extraAssets) - await action.downloadExtraAssets() + assets.forEach(a => { + action.extraAssets.push({ + asset: a, + instance: this.$refs.assetsOptions.find((c: any) => c.$attrs.name === a.name), + }) + }) + /** 若视频输出的插件设置了proxyExtraAssets,则由插件在runAction中处理 */ + if (!output?.proxyExtraAssets) { + await action.downloadExtraAssets() + } await output.runAction(action, instance) } catch (error) { logError(error) diff --git a/registry/lib/components/video/download/types.ts b/registry/lib/components/video/download/types.ts index 9f68a33ae..abcc677f9 100644 --- a/registry/lib/components/video/download/types.ts +++ b/registry/lib/components/video/download/types.ts @@ -77,11 +77,17 @@ export interface DownloadVideoApi extends WithName { /** 表示下载时额外附带的产物, 如弹幕 / 字幕等 */ export interface DownloadVideoAssets extends VueInstanceInput, WithName { getAssets: (infos: DownloadVideoInfo[], instance: AssetsParameter) => Promise + /** 获取可直接下载的链接 */ + getUrls?: ( + infos: DownloadVideoInfo[], + instance: AssetsParameter, + ) => Promise<{ name: string; url: string }[]> } /** 表示视频的下载信息以及携带的额外产物 */ -export class DownloadVideoAction { +export class DownloadVideoAction { readonly inputs: DownloadVideoInputItem[] = [] - extraAssets: PackageEntry[] = [] + /** 可下载的asset和对应的参数 */ + extraAssets: { asset: DownloadVideoAssets; instance: AssetsParameter }[] = [] constructor(public infos: DownloadVideoInfo[]) { this.inputs = infos.map(it => it.input) @@ -92,11 +98,19 @@ export class DownloadVideoAction { async downloadExtraAssets() { console.log('[downloadExtraAssets]', this.extraAssets) const filename = `${getFriendlyTitle(false)}.zip` - await new DownloadPackage(this.extraAssets).emit(filename) + const { infos } = this + const extraAssetsBlob = ( + await Promise.all( + this.extraAssets.map(({ asset, instance }) => asset.getAssets(infos, instance)), + ) + ).flat() + await new DownloadPackage(extraAssetsBlob).emit(filename) } } /** 下载视频的最终输出处理 */ export interface DownloadVideoOutput extends VueInstanceInput, WithName { runAction: (action: DownloadVideoAction, instance: OutputParameter) => Promise + /** 是否需要代理下载assets */ + proxyExtraAssets?: boolean description?: string } diff --git a/registry/lib/plugins/video/download/aria2-output/RpcConfig.vue b/registry/lib/plugins/video/download/aria2-output/RpcConfig.vue index 067638faa..9e2d05902 100644 --- a/registry/lib/plugins/video/download/aria2-output/RpcConfig.vue +++ b/registry/lib/plugins/video/download/aria2-output/RpcConfig.vue @@ -1,5 +1,9 @@ diff --git a/registry/lib/plugins/video/download/wasm-output/handler.ts b/registry/lib/plugins/video/download/wasm-output/handler.ts index 1f97330e3..3a22090ec 100644 --- a/registry/lib/plugins/video/download/wasm-output/handler.ts +++ b/registry/lib/plugins/video/download/wasm-output/handler.ts @@ -87,7 +87,7 @@ async function single( ) } -export async function run(action: DownloadVideoAction) { +export async function run(action: DownloadVideoAction, muxWithMetadata: boolean) { if (!ffmpeg.loaded) { await loadFFmpeg() } @@ -95,15 +95,17 @@ export async function run(action: DownloadVideoAction) { const { infos: pages, extraAssets } = action let ffmetadata: PackageEntry[] - const extraAssetsForBrowser = [] - for (const { asset, instance } of extraAssets) { - if (!ffmetadata && asset.name === 'saveVideoMetadata' && instance.type === 'ffmetadata') { - ffmetadata = await asset.getAssets(pages, instance) - } else { - extraAssetsForBrowser.push({ asset, instance }) + if (muxWithMetadata) { + const extraAssetsForBrowser = [] + for (const { asset, instance } of extraAssets) { + if (!ffmetadata && asset.name === 'saveVideoMetadata' && instance.type === 'ffmetadata') { + ffmetadata = await asset.getAssets(pages, instance) + } else { + extraAssetsForBrowser.push({ asset, instance }) + } } + action.extraAssets = extraAssetsForBrowser } - action.extraAssets = extraAssetsForBrowser const { dashAudioExtension, dashFlacAudioExtension, dashVideoExtension } = getComponentSettings('downloadVideo').options diff --git a/registry/lib/plugins/video/download/wasm-output/index.ts b/registry/lib/plugins/video/download/wasm-output/index.ts index 3cde08f64..d5039f259 100644 --- a/registry/lib/plugins/video/download/wasm-output/index.ts +++ b/registry/lib/plugins/video/download/wasm-output/index.ts @@ -19,14 +19,15 @@ export const plugin: PluginMetadata = { outputs.push({ name: 'wasm', displayName: 'WASM', - description: `${desc},运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件`, - runAction: async action => { + description: `${desc}。运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件。`, + runAction: async (action, instance) => { try { - await run(action) + await run(action, instance.muxWithMetadata) } catch (error) { Toast.error(String(error), title) } }, + component: () => import('./Config.vue').then(m => m.default), }) }) }, From 320a4f92eea41f04de869fb2dbdaa83e52cc4947 Mon Sep 17 00:00:00 2001 From: Liumingxun Date: Thu, 1 Aug 2024 11:08:00 +0800 Subject: [PATCH 15/29] feat: hide home carousel --- .eslintignore | 2 +- .../dist/components/style/simplify/home.js | 4 +-- .../components/style/simplify/home/home.scss | 25 ++++++++++++++++--- .../components/style/simplify/home/index.ts | 24 +++++++++++------- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/.eslintignore b/.eslintignore index 14e38d70a..c0ba0a5b9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,6 @@ packages/ typings/ -dist/ +**/dist/ dev/ node_modules/ !.github-json/ diff --git a/registry/dist/components/style/simplify/home.js b/registry/dist/components/style/simplify/home.js index 038a7eb61..ce9c14532 100644 --- a/registry/dist/components/style/simplify/home.js +++ b/registry/dist/components/style/simplify/home.js @@ -1,4 +1,4 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["style/simplify/home"]=t():e["style/simplify/home"]=t()}(globalThis,(()=>(()=>{var e,t,i={595:(e,t,i)=>{var n=i(355)((function(e){return e[1]}));n.push([e.id,"body.simplifyHome-switch-categories .z-top-container.has-menu {\n height: auto !important;\n min-height: unset !important;\n}\nbody.simplifyHome-switch-categories .bili-header-m > .bili-wrapper {\n visibility: hidden !important;\n height: 18px !important;\n}\nbody.simplifyHome-switch-categories .primary-menu-itnl {\n visibility: hidden !important;\n height: 24px !important;\n padding: 0 !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel {\n height: 12px !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel > * {\n display: none !important;\n}\nbody.simplifyHome-switch-categories.header-v3 .bili-wrapper {\n padding-top: 8px !important;\n border-top: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen #reportFirst1 {\n display: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen .space-between {\n margin-bottom: 0 !important;\n}\nbody.simplifyHome-switch-trends .bili-layout .bili-grid:first-child,\nbody.simplifyHome-switch-trends .recommended-container,\nbody.simplifyHome-switch-trends .rcmd-box-wrap {\n display: none !important;\n}\nbody.simplifyHome-switch-online .first-screen #reportFirst2 {\n display: none !important;\n}\nbody.simplifyHome-switch-ext-box .first-screen #reportFirst3 {\n display: none !important;\n}\nbody.simplifyHome-switch-special #bili_report_spe_rec {\n display: none !important;\n}\nbody.simplifyHome-switch-contact .bili-footer .b-footer-wrap,\nbody.simplifyHome-switch-contact .international-footer {\n display: none !important;\n}\nbody.simplifyHome-switch-elevator .storey-box .elevator {\n display: none !important;\n}",""]),e.exports=n},355:e=>{"use strict"; +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["style/simplify/home"]=t():e["style/simplify/home"]=t()}(globalThis,(()=>(()=>{var e,t,i={290:(e,t,i)=>{var n=i(218)((function(e){return e[1]}));n.push([e.id,"body.simplifyHome-switch-carousel .recommended-swipe.grid-anchor {\n display: none !important;\n}\nbody.simplifyHome-switch-categories .z-top-container.has-menu {\n height: auto !important;\n min-height: unset !important;\n}\nbody.simplifyHome-switch-categories .bili-header-m > .bili-wrapper {\n visibility: hidden !important;\n height: 18px !important;\n}\nbody.simplifyHome-switch-categories .primary-menu-itnl {\n visibility: hidden !important;\n height: 24px !important;\n padding: 0 !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel {\n height: 12px !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel > * {\n display: none !important;\n}\nbody.simplifyHome-switch-categories.header-v3 .bili-wrapper {\n padding-top: 8px !important;\n border-top: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen #reportFirst1 {\n display: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen .space-between {\n margin-bottom: 0 !important;\n}\nbody.simplifyHome-switch-trends .bili-layout .bili-grid:first-child,\nbody.simplifyHome-switch-trends .recommended-container,\nbody.simplifyHome-switch-trends .rcmd-box-wrap {\n display: none !important;\n}\nbody.simplifyHome-switch-online .first-screen #reportFirst2 {\n display: none !important;\n}\nbody.simplifyHome-switch-ext-box .first-screen #reportFirst3 {\n display: none !important;\n}\nbody.simplifyHome-switch-special #bili_report_spe_rec {\n display: none !important;\n}\nbody.simplifyHome-switch-contact .bili-footer .b-footer-wrap,\nbody.simplifyHome-switch-contact .international-footer {\n display: none !important;\n}\nbody.simplifyHome-switch-elevator .storey-box .elevator {\n display: none !important;\n}",""]),e.exports=n},218:e=>{"use strict"; // eslint-disable-next-line func-names e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var i=e(t);return t[2]?"@media ".concat(t[2]," {").concat(i,"}"):i})).join("")}, // eslint-disable-next-line func-names @@ -6,4 +6,4 @@ t.i=function(e,i,n){"string"==typeof e&&( // eslint-disable-next-line no-param-reassign e=[[null,e,""]]);var o={};if(n)for(var r=0;r{var n=i(595);n&&n.__esModule&&(n=n.default),e.exports="string"==typeof n?n:n.toString()}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,exports:{}};return i[e](r,r.exports,o),r.exports}t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,o.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}var r=Object.create(null);o.r(r);var a={};e=e||[null,t({}),t([]),t(t)];for(var s=2&n&&i;"object"==typeof s&&!~e.indexOf(s);s=t(s))Object.getOwnPropertyNames(s).forEach((e=>a[e]=()=>i[e]));return a.default=()=>i,o.d(r,a),r},o.d=(e,t)=>{for(var i in t)o.o(t,i)&&!o.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";o.d(r,{component:()=>d});const e=coreApis.componentApis.switchOptions,t=coreApis.settings,i=coreApis.spinQuery,n=coreApis.style,a=coreApis.utils,s=coreApis.utils.log,l=coreApis.utils.urls,p=(0,e.defineSwitchMetadata)({name:"simplifyOptions",dimAt:"checked",switchProps:{checkedIcon:"mdi-eye-off-outline",notCheckedIcon:"mdi-eye-outline"},switches:{categories:{defaultValue:!1,displayName:"分区栏"},trends:{defaultValue:!1,displayName:"活动/热门视频"},online:{defaultValue:!1,displayName:"在线列表(旧)"},"ext-box":{defaultValue:!1,displayName:"电竞赛事(旧)"},special:{defaultValue:!1,displayName:"特别推荐(旧)"},contact:{defaultValue:!1,displayName:"联系方式"},elevator:{defaultValue:!1,displayName:"右侧分区导航(旧)"}}}),c=(0,s.useScopedConsole)("简化首页"),d=(0,e.newSwitchComponentWrapper)(p)({name:"simplifyHome",displayName:"简化首页",description:"隐藏原版首页不需要的元素 / 分区.",instantStyles:[{name:"simplifyHome",style:()=>Promise.resolve().then(o.t.bind(o,262,23))}],urlInclude:l.mainSiteUrls,tags:[componentsTags.style],entry:async e=>{let{metadata:o}=e;const r=(0,a.matchUrlPattern)("https://www.bilibili.com/");if(!r)return;c.log("isHome",r);const{options:s}=(0,t.getComponentSettings)(o.name),l="-1"===(0,a.getCookieValue)("i-wanna-go-back"),d=await(async()=>{if(!l){const e=await(0,i.sq)((()=>dqa(".proxy-box > div")),(e=>e.length>0||!r));return Object.fromEntries(e.map((e=>[e.id.replace(/^bili_/,""),{displayName:e.querySelector("header .name")?.textContent?.trim()??"未知分区",defaultValue:!1}])))}const e=["推广"],t=await(0,i.sq)((()=>dqa(".bili-grid .the-world")),(e=>e.length>3||!r));c.log(t);const n=t?.filter((t=>!e.includes(t.id))).map((e=>{const t=(e=>{let t=e;for(;t.parentElement;){if(t.classList.contains("bili-grid"))return t;t=t.parentElement}return null})(e),i=e.id;return t?(t.dataset.area=i,[i,{displayName:i,defaultValue:!1}]):null})).filter((e=>null!==e))??[];return Object.fromEntries(n)})(),m={};Object.entries(d).forEach((e=>{let[i,{displayName:n,defaultValue:r}]=e;const a={defaultValue:r,displayName:n},l=`switch-${i}`;void 0===s[l]&&(s[l]=r);const c=`switch-${i}`;(0,t.addComponentListener)(`${o.name}.${c}`,(e=>{document.body.classList.toggle(`${o.name}-${c}`,e)}),!0),p.switches[i]=a,m[i]=a})),s.simplifyOptions.switches=m;const y=Object.keys(d).map((e=>`\n body.simplifyHome-switch-${e} .bili-layout .bili-grid[data-area="${e}"],\n body.simplifyHome-switch-${e} .storey-box .proxy-box #bili_${e} {\n display: none !important;\n }\n `.trim())).join("\n");(0,n.addStyle)(y,"simplify-home-generated")},commitHash:"cd5e421d84b8e446ac214166757f99b5ae8cdbfc",coreVersion:"2.7.3"})})(),r=r.component})())); \ No newline at end of file +var a=this[r][0];null!=a&&(o[a]=!0)}for(var s=0;s{var n=i(290);n&&n.__esModule&&(n=n.default),e.exports="string"==typeof n?n:n.toString()}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,exports:{}};return i[e](r,r.exports,o),r.exports}t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,o.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}var r=Object.create(null);o.r(r);var a={};e=e||[null,t({}),t([]),t(t)];for(var s=2&n&&i;"object"==typeof s&&!~e.indexOf(s);s=t(s))Object.getOwnPropertyNames(s).forEach((e=>a[e]=()=>i[e]));return a.default=()=>i,o.d(r,a),r},o.d=(e,t)=>{for(var i in t)o.o(t,i)&&!o.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";o.d(r,{component:()=>d});const e=coreApis.componentApis.switchOptions,t=coreApis.settings,i=coreApis.spinQuery,n=coreApis.style,a=coreApis.utils,s=coreApis.utils.log,l=coreApis.utils.urls,p=(0,e.defineSwitchMetadata)({name:"simplifyOptions",switches:{carousel:{defaultValue:!1,displayName:"轮播图"},categories:{defaultValue:!1,displayName:"分区栏"},trends:{defaultValue:!1,displayName:"活动/热门视频"},online:{defaultValue:!1,displayName:"在线列表(旧)"},"ext-box":{defaultValue:!1,displayName:"电竞赛事(旧)"},special:{defaultValue:!1,displayName:"特别推荐(旧)"},contact:{defaultValue:!1,displayName:"联系方式"},elevator:{defaultValue:!1,displayName:"右侧分区导航(旧)"}}}),c=(0,s.useScopedConsole)("简化首页"),d=(0,e.wrapSwitchOptions)(p)({name:"simplifyHome",displayName:"简化首页",description:"隐藏原版首页不需要的元素 / 分区.",instantStyles:[{name:"simplifyHome",style:()=>Promise.resolve().then(o.t.bind(o,446,23))}],urlInclude:l.mainSiteUrls,tags:[componentsTags.style],entry:async e=>{let{metadata:o}=e;const r=(0,a.matchUrlPattern)("https://www.bilibili.com/");if(!r)return;c.log("isHome",r);const{options:s}=(0,t.getComponentSettings)(o.name),l="-1"===(0,a.getCookieValue)("i-wanna-go-back"),d=await(async()=>{if(!l){const e=await(0,i.sq)((()=>dqa(".proxy-box > div")),(e=>e.length>0||!r));return e?Object.fromEntries(e.map((e=>[e.id.replace(/^bili_/,""),{displayName:e.querySelector("header .name")?.textContent?.trim()??"未知分区",defaultValue:!1}]))):{}}const e=["推广"],t=await(0,i.sq)((()=>dqa(".bili-grid .the-world")),(e=>e.length>3||!r));c.log(t);const n=t?.filter((t=>!e.includes(t.id))).map((e=>{const t=(e=>{let t=e;for(;t.parentElement;){if(t.classList.contains("bili-grid"))return t;t=t.parentElement}return null})(e),i=e.id;return t?(t.dataset.area=i,[i,{displayName:i,defaultValue:!1}]):null})).filter((e=>null!==e))??[];return Object.fromEntries(n)})(),m={};Object.entries(d).forEach((e=>{let[i,{displayName:n,defaultValue:r}]=e;const a={defaultValue:r,displayName:n},l=`switch-${i}`;void 0===s[l]&&(s[l]=r);const c=`switch-${i}`;(0,t.addComponentListener)(`${o.name}.${c}`,(e=>{document.body.classList.toggle(`${o.name}-${c}`,e)}),!0),p.switches[i]=a,m[i]=a})),s.simplifyOptions.switches=m;const y=Object.keys(d).map((e=>`\n body.simplifyHome-switch-${e} .bili-layout .bili-grid[data-area="${e}"],\n body.simplifyHome-switch-${e} .storey-box .proxy-box #bili_${e} {\n display: none !important;\n }\n `.trim())).join("\n");(0,n.addStyle)(y,"simplify-home-generated")},commitHash:"a1df99ac12a1d5c7b5ecdf974ee3915a0bc96bbf",coreVersion:"2.9.0"})})(),r=r.component})())); \ No newline at end of file diff --git a/registry/lib/components/style/simplify/home/home.scss b/registry/lib/components/style/simplify/home/home.scss index 66e28c38f..b5343ba16 100644 --- a/registry/lib/components/style/simplify/home/home.scss +++ b/registry/lib/components/style/simplify/home/home.scss @@ -1,33 +1,46 @@ body.simplifyHome-switch { + &-carousel { + .recommended-swipe.grid-anchor { + display: none !important; + } + } + &-categories { .z-top-container.has-menu { height: auto !important; min-height: unset !important; } - .bili-header-m > .bili-wrapper { + + .bili-header-m>.bili-wrapper { visibility: hidden !important; height: 18px !important; } + .primary-menu-itnl { visibility: hidden !important; height: 24px !important; padding: 0 !important; } + .bili-header__channel { height: 12px !important; } - .bili-header__channel > * { + + .bili-header__channel>* { display: none !important; } + &.header-v3 .bili-wrapper { padding-top: 8px !important; border-top: none !important; } } + &-trends { .first-screen #reportFirst1 { display: none !important; } + .first-screen .space-between { margin-bottom: 0 !important; } @@ -38,30 +51,36 @@ body.simplifyHome-switch { display: none !important; } } + &-online { .first-screen #reportFirst2 { display: none !important; } } + &-ext-box { .first-screen #reportFirst3 { display: none !important; } } + &-special { #bili_report_spe_rec { display: none !important; } } + &-contact { + .bili-footer .b-footer-wrap, .international-footer { display: none !important; } } + &-elevator { .storey-box .elevator { display: none !important; } } -} +} \ No newline at end of file diff --git a/registry/lib/components/style/simplify/home/index.ts b/registry/lib/components/style/simplify/home/index.ts index f1bddf73a..b2bd121af 100644 --- a/registry/lib/components/style/simplify/home/index.ts +++ b/registry/lib/components/style/simplify/home/index.ts @@ -10,6 +10,10 @@ import { mainSiteUrls } from '@/core/utils/urls' const switchMetadata = defineSwitchMetadata({ name: 'simplifyOptions', switches: { + carousel: { + defaultValue: false, + displayName: '轮播图', + }, categories: { defaultValue: false, displayName: '分区栏', @@ -74,15 +78,17 @@ export const component = wrapSwitchOptions(switchMetadata)({ () => dqa('.proxy-box > div'), elements => elements.length > 0 || !isHome, ) - return Object.fromEntries( - categoryElements.map(it => [ - it.id.replace(/^bili_/, ''), - { - displayName: it.querySelector('header .name')?.textContent?.trim() ?? '未知分区', - defaultValue: false, - }, - ]), - ) + return categoryElements + ? Object.fromEntries( + categoryElements.map(it => [ + it.id.replace(/^bili_/, ''), + { + displayName: it.querySelector('header .name')?.textContent?.trim() ?? '未知分区', + defaultValue: false, + }, + ]), + ) + : {} } const skipIds = ['推广'] From 573f693e8c5c8e723e1c9a44c2c75c141c679b9b Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Sun, 4 Aug 2024 00:22:53 +0800 Subject: [PATCH 16/29] feat: Add clickable link for liveroom users --- .../live/liveroom-username-link/index.ts | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 registry/lib/components/live/liveroom-username-link/index.ts diff --git a/registry/lib/components/live/liveroom-username-link/index.ts b/registry/lib/components/live/liveroom-username-link/index.ts new file mode 100644 index 000000000..08903ba01 --- /dev/null +++ b/registry/lib/components/live/liveroom-username-link/index.ts @@ -0,0 +1,101 @@ +import { defineComponentMetadata } from '@/components/define' +import { select } from '@/core/spin-query' +import { delay } from '@/core/utils' + +const processed = new WeakSet() + +const entry = async () => { + const userInfoBar = await select('#rank-list-ctnr-box', { + queryInterval: 500, + }) + + const observer = new MutationObserver(async () => { + // 舰长列表 + const guardNodes = [...document.querySelectorAll('webcomponent-userinfo')] + let subtreeLoaded = false + + for (const node of guardNodes) { + if (processed.has(node)) { + continue + } + + // eslint-disable-next-line no-underscore-dangle + const { uid } = (node as any).__vue__.source.uinfo + + if (!subtreeLoaded) { + // 等待子节点创建 + while ( + node.shadowRoot.querySelector('a') === null || + node.shadowRoot.querySelector('.faceBox') === null + ) { + await delay(100) + } + subtreeLoaded = true + } + + const a = node.shadowRoot.querySelector('a') + const avatar: HTMLDivElement = node.shadowRoot.querySelector('.faceBox') + + a.href = `https://space.bilibili.com/${uid}` + a.style.textDecoration = 'none' + + avatar.style.cursor = 'pointer' + avatar.addEventListener('click', () => { + window.open(`https://space.bilibili.com/${uid}`) + }) + processed.add(node) + + // const name = a.innerText + // console.log(`已为舰长${name}(UID: ${uid})添加超链接`) + } + + // 观众列表 + const spectorNodes = [...document.querySelectorAll('.gift-rank-list-item')] + for (const node of spectorNodes) { + if (processed.has(node)) { + continue + } + + // eslint-disable-next-line no-underscore-dangle + const { uid } = (node as any).__vue__.source + const nameNode: HTMLDivElement = node.querySelector('.common-nickname-wrapper .name') + + // 名称 + nameNode.style.cursor = 'pointer' + nameNode.addEventListener('click', () => { + window.open(`https://space.bilibili.com/${uid}`) + }) + + // 头像 + const avatar: HTMLDivElement = node.querySelector('.face') + avatar.style.cursor = 'pointer' + avatar.addEventListener('click', () => { + window.open(`https://space.bilibili.com/${uid}`) + }) + processed.add(node) + + // const name = nameNode.innerText + // console.log(`已为观众${name}(UID: ${uid})添加超链接`) + } + }) + + observer.observe(userInfoBar, { + childList: true, + subtree: true, + }) +} + +export const component = defineComponentMetadata({ + name: 'liveroomUsernameLink', + author: { + name: 'Light_Quanta', + link: 'https://github.com/LightQuanta', + }, + displayName: '添加直播间用户超链接', + entry, + tags: [componentsTags.live], + urlInclude: [/^https:\/\/live\.bilibili\.com\/\d+/], + description: { + 'zh-CN': '为直播间的房间观众和大航海界面的用户列表添加可以点击的超链接', + }, +}) From 442c281c252133b4a204ff3033506ea914c14b75 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Thu, 8 Aug 2024 21:21:17 +0800 Subject: [PATCH 17/29] fix: use correct uid retrieval method for audience element --- .../live/liveroom-username-link/index.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/registry/lib/components/live/liveroom-username-link/index.ts b/registry/lib/components/live/liveroom-username-link/index.ts index 08903ba01..a55bf1a1f 100644 --- a/registry/lib/components/live/liveroom-username-link/index.ts +++ b/registry/lib/components/live/liveroom-username-link/index.ts @@ -33,14 +33,14 @@ const entry = async () => { subtreeLoaded = true } - const a = node.shadowRoot.querySelector('a') - const avatar: HTMLDivElement = node.shadowRoot.querySelector('.faceBox') + const aNode = node.shadowRoot.querySelector('a') + const avatarNode: HTMLDivElement = node.shadowRoot.querySelector('.faceBox') - a.href = `https://space.bilibili.com/${uid}` - a.style.textDecoration = 'none' + aNode.href = `https://space.bilibili.com/${uid}` + aNode.style.textDecoration = 'none' - avatar.style.cursor = 'pointer' - avatar.addEventListener('click', () => { + avatarNode.style.cursor = 'pointer' + avatarNode.addEventListener('click', () => { window.open(`https://space.bilibili.com/${uid}`) }) processed.add(node) @@ -56,20 +56,23 @@ const entry = async () => { continue } - // eslint-disable-next-line no-underscore-dangle - const { uid } = (node as any).__vue__.source - const nameNode: HTMLDivElement = node.querySelector('.common-nickname-wrapper .name') + // 观众列表元素似乎会原地更新,不能直接预先获取UID并绑定,这里通过点击时获取父元素动态读取UID // 名称 + const nameNode: HTMLDivElement = node.querySelector('.common-nickname-wrapper .name') nameNode.style.cursor = 'pointer' nameNode.addEventListener('click', () => { + // eslint-disable-next-line no-underscore-dangle + const { uid } = (nameNode as any).parentNode.parentNode.parentNode.parentNode.__vue__.source window.open(`https://space.bilibili.com/${uid}`) }) // 头像 - const avatar: HTMLDivElement = node.querySelector('.face') - avatar.style.cursor = 'pointer' - avatar.addEventListener('click', () => { + const avatarNode: HTMLDivElement = node.querySelector('.face') + avatarNode.style.cursor = 'pointer' + avatarNode.addEventListener('click', () => { + // eslint-disable-next-line no-underscore-dangle + const { uid } = (avatarNode as any).parentNode.parentNode.__vue__.source window.open(`https://space.bilibili.com/${uid}`) }) processed.add(node) From 96c5c062e62b4aa65d065d2e3ab86fb6b3723f22 Mon Sep 17 00:00:00 2001 From: WakelessSloth56 Date: Fri, 9 Aug 2024 11:08:24 +0800 Subject: [PATCH 18/29] feat: wasm plugin - parallel download libs and audio,video --- .../video/download/wasm-output/handler.ts | 60 ++++++++++--------- .../video/download/wasm-output/utils.ts | 22 ++++--- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/registry/lib/plugins/video/download/wasm-output/handler.ts b/registry/lib/plugins/video/download/wasm-output/handler.ts index 3a22090ec..7d6842e1c 100644 --- a/registry/lib/plugins/video/download/wasm-output/handler.ts +++ b/registry/lib/plugins/video/download/wasm-output/handler.ts @@ -6,38 +6,38 @@ import { title as pluginTitle } from '.' import type { Options } from '../../../../components/video/download' import { DownloadVideoAction } from '../../../../components/video/download/types' import { FFmpeg } from './ffmpeg' -import { getCacheOrGet, httpGet, toastProgress, toBlobUrl } from './utils' +import { getCacheOrFetch, httpGet, toastProgress, toBlobUrl } from './utils' const ffmpeg = new FFmpeg() async function loadFFmpeg() { const toast = Toast.info('正在加载 FFmpeg', `${pluginTitle} - 初始化`) + + const progress = toastProgress(toast) + const [worker, core, wasm] = await Promise.all([ + getCacheOrFetch( + 'ffmpeg-worker', + meta.compilationInfo.altCdn.library.ffmpeg.worker, + progress(0, '正在加载 FFmpeg Worker'), + ), + getCacheOrFetch( + 'ffmpeg-core', + meta.compilationInfo.altCdn.library.ffmpeg.core, + progress(1, '正在加载 FFmpeg Core'), + ), + getCacheOrFetch( + 'ffmpeg-wasm', + meta.compilationInfo.altCdn.library.ffmpeg.wasm, + progress(2, '正在加载 FFmpeg WASM'), + ), + ]) + await ffmpeg.load({ - workerLoadURL: toBlobUrl( - await getCacheOrGet( - 'ffmpeg-worker', - meta.compilationInfo.altCdn.library.ffmpeg.worker, - toastProgress(toast, '正在加载 FFmpeg Worker'), - ), - 'text/javascript', - ), - coreURL: toBlobUrl( - await getCacheOrGet( - 'ffmpeg-core', - meta.compilationInfo.altCdn.library.ffmpeg.core, - toastProgress(toast, '正在加载 FFmpeg Core'), - ), - 'text/javascript', - ), - wasmURL: toBlobUrl( - await getCacheOrGet( - 'ffmpeg-wasm', - meta.compilationInfo.altCdn.library.ffmpeg.wasm, - toastProgress(toast, '正在加载 FFmpeg WASM'), - ), - 'application/wasm', - ), + workerLoadURL: toBlobUrl(worker, 'text/javascript'), + coreURL: toBlobUrl(core, 'text/javascript'), + wasmURL: toBlobUrl(wasm, 'application/wasm'), }) + toast.message = '完成!' toast.close() } @@ -53,8 +53,14 @@ async function single( ) { const toast = Toast.info('', `${pluginTitle} - ${pageIndex} / ${totalPages}`) - ffmpeg.writeFile('video', await httpGet(videoUrl, toastProgress(toast, '正在下载视频流'))) - ffmpeg.writeFile('audio', await httpGet(audioUrl, toastProgress(toast, '正在下载音频流'))) + const progress = toastProgress(toast) + const [video, audio] = await Promise.all([ + httpGet(videoUrl, progress(0, '正在下载视频流')), + httpGet(audioUrl, progress(1, '正在下载音频流')), + ]) + + ffmpeg.writeFile('video', video) + ffmpeg.writeFile('audio', audio) const args = ['-i', 'video', '-i', 'audio'] diff --git a/registry/lib/plugins/video/download/wasm-output/utils.ts b/registry/lib/plugins/video/download/wasm-output/utils.ts index 165e3559d..fb02e15ad 100644 --- a/registry/lib/plugins/video/download/wasm-output/utils.ts +++ b/registry/lib/plugins/video/download/wasm-output/utils.ts @@ -2,13 +2,21 @@ import { Toast } from '@/core/toast' import { formatFileSize, formatPercent } from '@/core/utils/formatters' import { getOrLoad, storeNames } from './database' -type OnProgress = (received: number, length: number) => void +type OnProgress = (received: number, total: number) => void -export function toastProgress(toast: Toast, message: string): OnProgress { - return (r, l) => { - toast.message = `${message}: ${formatFileSize(r)}${ - l > 0 ? ` / ${formatFileSize(l)} @ ${formatPercent(r / l)}` : '' - }` +function formatProgress(received: number, total: number) { + return `${formatFileSize(received)}${ + total > 0 ? ` / ${formatFileSize(total)} @ ${formatPercent(received / total)}` : '' + }` +} + +export function toastProgress(toast: Toast) { + const lines = [] + return (line: number, message: string): OnProgress => { + return (r, l) => { + lines[line] = `${message}: ${formatProgress(r, l)}` + toast.message = lines.join('\n') + } } } @@ -48,7 +56,7 @@ export async function httpGet(url: string, onprogress: OnProgress) { return chunksAll } -export async function getCacheOrGet(key: string, url: string, loading: OnProgress) { +export async function getCacheOrFetch(key: string, url: string, loading: OnProgress) { return getOrLoad(storeNames.cache, key, async () => httpGet(url, loading)) } From 51bed55f3f5d3c2605e5ebb434bc6c49aff8cac2 Mon Sep 17 00:00:00 2001 From: Liumingxun Date: Mon, 12 Aug 2024 09:21:54 +0800 Subject: [PATCH 19/29] chore: remove dist --- registry/dist/components/style/simplify/home.js | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 registry/dist/components/style/simplify/home.js diff --git a/registry/dist/components/style/simplify/home.js b/registry/dist/components/style/simplify/home.js deleted file mode 100644 index ce9c14532..000000000 --- a/registry/dist/components/style/simplify/home.js +++ /dev/null @@ -1,9 +0,0 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["style/simplify/home"]=t():e["style/simplify/home"]=t()}(globalThis,(()=>(()=>{var e,t,i={290:(e,t,i)=>{var n=i(218)((function(e){return e[1]}));n.push([e.id,"body.simplifyHome-switch-carousel .recommended-swipe.grid-anchor {\n display: none !important;\n}\nbody.simplifyHome-switch-categories .z-top-container.has-menu {\n height: auto !important;\n min-height: unset !important;\n}\nbody.simplifyHome-switch-categories .bili-header-m > .bili-wrapper {\n visibility: hidden !important;\n height: 18px !important;\n}\nbody.simplifyHome-switch-categories .primary-menu-itnl {\n visibility: hidden !important;\n height: 24px !important;\n padding: 0 !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel {\n height: 12px !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel > * {\n display: none !important;\n}\nbody.simplifyHome-switch-categories.header-v3 .bili-wrapper {\n padding-top: 8px !important;\n border-top: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen #reportFirst1 {\n display: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen .space-between {\n margin-bottom: 0 !important;\n}\nbody.simplifyHome-switch-trends .bili-layout .bili-grid:first-child,\nbody.simplifyHome-switch-trends .recommended-container,\nbody.simplifyHome-switch-trends .rcmd-box-wrap {\n display: none !important;\n}\nbody.simplifyHome-switch-online .first-screen #reportFirst2 {\n display: none !important;\n}\nbody.simplifyHome-switch-ext-box .first-screen #reportFirst3 {\n display: none !important;\n}\nbody.simplifyHome-switch-special #bili_report_spe_rec {\n display: none !important;\n}\nbody.simplifyHome-switch-contact .bili-footer .b-footer-wrap,\nbody.simplifyHome-switch-contact .international-footer {\n display: none !important;\n}\nbody.simplifyHome-switch-elevator .storey-box .elevator {\n display: none !important;\n}",""]),e.exports=n},218:e=>{"use strict"; -// eslint-disable-next-line func-names -e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var i=e(t);return t[2]?"@media ".concat(t[2]," {").concat(i,"}"):i})).join("")}, -// eslint-disable-next-line func-names -t.i=function(e,i,n){"string"==typeof e&&( -// eslint-disable-next-line no-param-reassign -e=[[null,e,""]]);var o={};if(n)for(var r=0;r{var n=i(290);n&&n.__esModule&&(n=n.default),e.exports="string"==typeof n?n:n.toString()}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,exports:{}};return i[e](r,r.exports,o),r.exports}t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,o.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}var r=Object.create(null);o.r(r);var a={};e=e||[null,t({}),t([]),t(t)];for(var s=2&n&&i;"object"==typeof s&&!~e.indexOf(s);s=t(s))Object.getOwnPropertyNames(s).forEach((e=>a[e]=()=>i[e]));return a.default=()=>i,o.d(r,a),r},o.d=(e,t)=>{for(var i in t)o.o(t,i)&&!o.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";o.d(r,{component:()=>d});const e=coreApis.componentApis.switchOptions,t=coreApis.settings,i=coreApis.spinQuery,n=coreApis.style,a=coreApis.utils,s=coreApis.utils.log,l=coreApis.utils.urls,p=(0,e.defineSwitchMetadata)({name:"simplifyOptions",switches:{carousel:{defaultValue:!1,displayName:"轮播图"},categories:{defaultValue:!1,displayName:"分区栏"},trends:{defaultValue:!1,displayName:"活动/热门视频"},online:{defaultValue:!1,displayName:"在线列表(旧)"},"ext-box":{defaultValue:!1,displayName:"电竞赛事(旧)"},special:{defaultValue:!1,displayName:"特别推荐(旧)"},contact:{defaultValue:!1,displayName:"联系方式"},elevator:{defaultValue:!1,displayName:"右侧分区导航(旧)"}}}),c=(0,s.useScopedConsole)("简化首页"),d=(0,e.wrapSwitchOptions)(p)({name:"simplifyHome",displayName:"简化首页",description:"隐藏原版首页不需要的元素 / 分区.",instantStyles:[{name:"simplifyHome",style:()=>Promise.resolve().then(o.t.bind(o,446,23))}],urlInclude:l.mainSiteUrls,tags:[componentsTags.style],entry:async e=>{let{metadata:o}=e;const r=(0,a.matchUrlPattern)("https://www.bilibili.com/");if(!r)return;c.log("isHome",r);const{options:s}=(0,t.getComponentSettings)(o.name),l="-1"===(0,a.getCookieValue)("i-wanna-go-back"),d=await(async()=>{if(!l){const e=await(0,i.sq)((()=>dqa(".proxy-box > div")),(e=>e.length>0||!r));return e?Object.fromEntries(e.map((e=>[e.id.replace(/^bili_/,""),{displayName:e.querySelector("header .name")?.textContent?.trim()??"未知分区",defaultValue:!1}]))):{}}const e=["推广"],t=await(0,i.sq)((()=>dqa(".bili-grid .the-world")),(e=>e.length>3||!r));c.log(t);const n=t?.filter((t=>!e.includes(t.id))).map((e=>{const t=(e=>{let t=e;for(;t.parentElement;){if(t.classList.contains("bili-grid"))return t;t=t.parentElement}return null})(e),i=e.id;return t?(t.dataset.area=i,[i,{displayName:i,defaultValue:!1}]):null})).filter((e=>null!==e))??[];return Object.fromEntries(n)})(),m={};Object.entries(d).forEach((e=>{let[i,{displayName:n,defaultValue:r}]=e;const a={defaultValue:r,displayName:n},l=`switch-${i}`;void 0===s[l]&&(s[l]=r);const c=`switch-${i}`;(0,t.addComponentListener)(`${o.name}.${c}`,(e=>{document.body.classList.toggle(`${o.name}-${c}`,e)}),!0),p.switches[i]=a,m[i]=a})),s.simplifyOptions.switches=m;const y=Object.keys(d).map((e=>`\n body.simplifyHome-switch-${e} .bili-layout .bili-grid[data-area="${e}"],\n body.simplifyHome-switch-${e} .storey-box .proxy-box #bili_${e} {\n display: none !important;\n }\n `.trim())).join("\n");(0,n.addStyle)(y,"simplify-home-generated")},commitHash:"a1df99ac12a1d5c7b5ecdf974ee3915a0bc96bbf",coreVersion:"2.9.0"})})(),r=r.component})())); \ No newline at end of file From e7957ab3e1c28bdd1d7ecf8e660856e786a9f2ad Mon Sep 17 00:00:00 2001 From: Liumingxun Date: Mon, 12 Aug 2024 10:46:58 +0800 Subject: [PATCH 20/29] chore: reset simplify home dist from a1df99ac --- registry/dist/components/style/simplify/home.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 registry/dist/components/style/simplify/home.js diff --git a/registry/dist/components/style/simplify/home.js b/registry/dist/components/style/simplify/home.js new file mode 100644 index 000000000..038a7eb61 --- /dev/null +++ b/registry/dist/components/style/simplify/home.js @@ -0,0 +1,9 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["style/simplify/home"]=t():e["style/simplify/home"]=t()}(globalThis,(()=>(()=>{var e,t,i={595:(e,t,i)=>{var n=i(355)((function(e){return e[1]}));n.push([e.id,"body.simplifyHome-switch-categories .z-top-container.has-menu {\n height: auto !important;\n min-height: unset !important;\n}\nbody.simplifyHome-switch-categories .bili-header-m > .bili-wrapper {\n visibility: hidden !important;\n height: 18px !important;\n}\nbody.simplifyHome-switch-categories .primary-menu-itnl {\n visibility: hidden !important;\n height: 24px !important;\n padding: 0 !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel {\n height: 12px !important;\n}\nbody.simplifyHome-switch-categories .bili-header__channel > * {\n display: none !important;\n}\nbody.simplifyHome-switch-categories.header-v3 .bili-wrapper {\n padding-top: 8px !important;\n border-top: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen #reportFirst1 {\n display: none !important;\n}\nbody.simplifyHome-switch-trends .first-screen .space-between {\n margin-bottom: 0 !important;\n}\nbody.simplifyHome-switch-trends .bili-layout .bili-grid:first-child,\nbody.simplifyHome-switch-trends .recommended-container,\nbody.simplifyHome-switch-trends .rcmd-box-wrap {\n display: none !important;\n}\nbody.simplifyHome-switch-online .first-screen #reportFirst2 {\n display: none !important;\n}\nbody.simplifyHome-switch-ext-box .first-screen #reportFirst3 {\n display: none !important;\n}\nbody.simplifyHome-switch-special #bili_report_spe_rec {\n display: none !important;\n}\nbody.simplifyHome-switch-contact .bili-footer .b-footer-wrap,\nbody.simplifyHome-switch-contact .international-footer {\n display: none !important;\n}\nbody.simplifyHome-switch-elevator .storey-box .elevator {\n display: none !important;\n}",""]),e.exports=n},355:e=>{"use strict"; +// eslint-disable-next-line func-names +e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var i=e(t);return t[2]?"@media ".concat(t[2]," {").concat(i,"}"):i})).join("")}, +// eslint-disable-next-line func-names +t.i=function(e,i,n){"string"==typeof e&&( +// eslint-disable-next-line no-param-reassign +e=[[null,e,""]]);var o={};if(n)for(var r=0;r{var n=i(595);n&&n.__esModule&&(n=n.default),e.exports="string"==typeof n?n:n.toString()}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={id:e,exports:{}};return i[e](r,r.exports,o),r.exports}t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,o.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}var r=Object.create(null);o.r(r);var a={};e=e||[null,t({}),t([]),t(t)];for(var s=2&n&&i;"object"==typeof s&&!~e.indexOf(s);s=t(s))Object.getOwnPropertyNames(s).forEach((e=>a[e]=()=>i[e]));return a.default=()=>i,o.d(r,a),r},o.d=(e,t)=>{for(var i in t)o.o(t,i)&&!o.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";o.d(r,{component:()=>d});const e=coreApis.componentApis.switchOptions,t=coreApis.settings,i=coreApis.spinQuery,n=coreApis.style,a=coreApis.utils,s=coreApis.utils.log,l=coreApis.utils.urls,p=(0,e.defineSwitchMetadata)({name:"simplifyOptions",dimAt:"checked",switchProps:{checkedIcon:"mdi-eye-off-outline",notCheckedIcon:"mdi-eye-outline"},switches:{categories:{defaultValue:!1,displayName:"分区栏"},trends:{defaultValue:!1,displayName:"活动/热门视频"},online:{defaultValue:!1,displayName:"在线列表(旧)"},"ext-box":{defaultValue:!1,displayName:"电竞赛事(旧)"},special:{defaultValue:!1,displayName:"特别推荐(旧)"},contact:{defaultValue:!1,displayName:"联系方式"},elevator:{defaultValue:!1,displayName:"右侧分区导航(旧)"}}}),c=(0,s.useScopedConsole)("简化首页"),d=(0,e.newSwitchComponentWrapper)(p)({name:"simplifyHome",displayName:"简化首页",description:"隐藏原版首页不需要的元素 / 分区.",instantStyles:[{name:"simplifyHome",style:()=>Promise.resolve().then(o.t.bind(o,262,23))}],urlInclude:l.mainSiteUrls,tags:[componentsTags.style],entry:async e=>{let{metadata:o}=e;const r=(0,a.matchUrlPattern)("https://www.bilibili.com/");if(!r)return;c.log("isHome",r);const{options:s}=(0,t.getComponentSettings)(o.name),l="-1"===(0,a.getCookieValue)("i-wanna-go-back"),d=await(async()=>{if(!l){const e=await(0,i.sq)((()=>dqa(".proxy-box > div")),(e=>e.length>0||!r));return Object.fromEntries(e.map((e=>[e.id.replace(/^bili_/,""),{displayName:e.querySelector("header .name")?.textContent?.trim()??"未知分区",defaultValue:!1}])))}const e=["推广"],t=await(0,i.sq)((()=>dqa(".bili-grid .the-world")),(e=>e.length>3||!r));c.log(t);const n=t?.filter((t=>!e.includes(t.id))).map((e=>{const t=(e=>{let t=e;for(;t.parentElement;){if(t.classList.contains("bili-grid"))return t;t=t.parentElement}return null})(e),i=e.id;return t?(t.dataset.area=i,[i,{displayName:i,defaultValue:!1}]):null})).filter((e=>null!==e))??[];return Object.fromEntries(n)})(),m={};Object.entries(d).forEach((e=>{let[i,{displayName:n,defaultValue:r}]=e;const a={defaultValue:r,displayName:n},l=`switch-${i}`;void 0===s[l]&&(s[l]=r);const c=`switch-${i}`;(0,t.addComponentListener)(`${o.name}.${c}`,(e=>{document.body.classList.toggle(`${o.name}-${c}`,e)}),!0),p.switches[i]=a,m[i]=a})),s.simplifyOptions.switches=m;const y=Object.keys(d).map((e=>`\n body.simplifyHome-switch-${e} .bili-layout .bili-grid[data-area="${e}"],\n body.simplifyHome-switch-${e} .storey-box .proxy-box #bili_${e} {\n display: none !important;\n }\n `.trim())).join("\n");(0,n.addStyle)(y,"simplify-home-generated")},commitHash:"cd5e421d84b8e446ac214166757f99b5ae8cdbfc",coreVersion:"2.7.3"})})(),r=r.component})())); \ No newline at end of file From d477d8ca5ff7a93e0be7deb0723695495fac4e00 Mon Sep 17 00:00:00 2001 From: the1812 Date: Thu, 15 Aug 2024 23:13:00 +0800 Subject: [PATCH 21/29] Update docs --- doc/features/features.json | 16 ++++++++++++++++ doc/features/features.md | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/doc/features/features.json b/doc/features/features.json index eb3ee9ee8..8d1829830 100644 --- a/doc/features/features.json +++ b/doc/features/features.json @@ -143,6 +143,14 @@ "fullRelativePath": "../../registry/dist/components/live/home-mute.js", "fullAbsolutePath": "registry/dist/components/live/home-mute.js" }, + { + "type": "component", + "name": "liveroomUsernameLink", + "displayName": "添加直播间用户超链接", + "description": "by [@Light_Quanta](https://github.com/LightQuanta)\n\n为直播间的房间观众和大航海界面的用户列表添加可以点击的超链接", + "fullRelativePath": "../../registry/dist/components/live/liveroom-username-link.js", + "fullAbsolutePath": "registry/dist/components/live/liveroom-username-link.js" + }, { "type": "component", "name": "originalLiveroom", @@ -735,6 +743,14 @@ "fullRelativePath": "../../registry/dist/components/video/full-episode-title.js", "fullAbsolutePath": "registry/dist/components/video/full-episode-title.js" }, + { + "type": "component", + "name": "saveVideoMetadata", + "displayName": "保存视频元数据", + "description": "by [@WakelessSloth56](https://github.com/WakelessSloth56),[@LainIO24](https://github.com/LainIO24)\n\n保存视频元数据(标题、描述、UP、章节等)", + "fullRelativePath": "../../registry/dist/components/video/metadata.js", + "fullAbsolutePath": "registry/dist/components/video/metadata.js" + }, { "type": "component", "name": "outerWatchlater", diff --git a/doc/features/features.md b/doc/features/features.md index 7e143954e..ee4dcfa8b 100644 --- a/doc/features/features.md +++ b/doc/features/features.md @@ -179,6 +179,17 @@ by [@TimmyOVO](https://github.com/TimmyOVO) 禁止直播首页的推荐直播间自动开始播放. +### [添加直播间用户超链接](../../registry/dist/components/live/liveroom-username-link.js) +`liveroomUsernameLink` + +**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/live/liveroom-username-link.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/live/liveroom-username-link.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/live/liveroom-username-link.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/live/liveroom-username-link.js) + +by [@Light_Quanta](https://github.com/LightQuanta) + +为直播间的房间观众和大航海界面的用户列表添加可以点击的超链接 + ### [返回原版直播间](../../registry/dist/components/live/original.js) `originalLiveroom` @@ -1022,6 +1033,17 @@ by [@kdxcxs](https://github.com/kdxcxs) 打开 `展开选集列表` 时, 在选集区域的标题上按住 Alt 键点击可以临时切换展开/收起选集列表. +### [保存视频元数据](../../registry/dist/components/video/metadata.js) +`saveVideoMetadata` + +**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/video/metadata.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/video/metadata.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/metadata.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/metadata.js) + +by [@WakelessSloth56](https://github.com/WakelessSloth56),[@LainIO24](https://github.com/LainIO24) + +保存视频元数据(标题、描述、UP、章节等) + ### [外置稍后再看](../../registry/dist/components/video/outer-watchlater.js) `outerWatchlater` From 8caf5564faf24e4b6299a67a793d4c1170de9673 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 15:52:21 +0800 Subject: [PATCH 22/29] Add forward slash support (#4865) --- .../video/danmaku/unescape/index.md | 2 +- .../video/danmaku/unescape/index.ts | 32 +++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/registry/lib/components/video/danmaku/unescape/index.md b/registry/lib/components/video/danmaku/unescape/index.md index e84e41531..f2cd57af7 100644 --- a/registry/lib/components/video/danmaku/unescape/index.md +++ b/registry/lib/components/video/danmaku/unescape/index.md @@ -1 +1 @@ -将弹幕中的 `\n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠. +将弹幕中的 `\n` 或 `/n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠. diff --git a/registry/lib/components/video/danmaku/unescape/index.ts b/registry/lib/components/video/danmaku/unescape/index.ts index 4e8118923..35ed7c08d 100644 --- a/registry/lib/components/video/danmaku/unescape/index.ts +++ b/registry/lib/components/video/danmaku/unescape/index.ts @@ -5,13 +5,39 @@ export const component = defineComponentMetadata({ name: 'unescapeDanmaku', displayName: '弹幕转义', tags: [componentsTags.video], - entry: () => { - const newLineRegex = /\\n/g + options: { + backSlash: { + defaultValue: true, + displayName: '对 \\n 转义', + }, + forwardSlash: { + defaultValue: true, + displayName: '对 /n 转义', + }, + }, + entry: ({ settings }) => { + const newLineRegex = (() => { + if (settings.options.backSlash && settings.options.forwardSlash) { + return /\\n|\/n/g + } + if (settings.options.backSlash) { + return /\\n/g + } + return /\/n/g + })() + const setText = (element: Element, text: string): void => { + const children = [...element.children] + if (children.length > 0) { + children.forEach(child => setText(child, text)) + } + const textNodes = [...element.childNodes].filter(it => it.nodeType === Node.TEXT_NODE) + textNodes.forEach(node => (node.textContent = text)) + } forEachVideoDanmaku({ added: danmaku => { if (newLineRegex.test(danmaku.text)) { const newText = danmaku.text.replace(newLineRegex, '\n') - danmaku.element.textContent = newText + setText(danmaku.element, newText) } }, }) From 23a1f4081fadd411e1c08654d05daf850ff5d582 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 16:01:56 +0800 Subject: [PATCH 23/29] Fix icon size --- src/components/SwitchOptions.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/SwitchOptions.vue b/src/components/SwitchOptions.vue index 152b871fc..68fe1d161 100644 --- a/src/components/SwitchOptions.vue +++ b/src/components/SwitchOptions.vue @@ -5,7 +5,7 @@ {{ options.optionDisplayName }} @@ -128,6 +128,7 @@ export default Vue.extend({ } .switch-icon { margin-right: 8px; + opacity: 0.75; transform: scale(0.9); } .dim { From 9c1f318c9b9199446a6f15550a615df58504c4db Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 16:02:12 +0800 Subject: [PATCH 24/29] Add widget support (#2666) --- .../components/style/custom-navbar/index.ts | 3 +++ .../style/custom-navbar/settings/Widget.vue | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 registry/lib/components/style/custom-navbar/settings/Widget.vue diff --git a/registry/lib/components/style/custom-navbar/index.ts b/registry/lib/components/style/custom-navbar/index.ts index 98eaf0579..4e9385bd7 100644 --- a/registry/lib/components/style/custom-navbar/index.ts +++ b/registry/lib/components/style/custom-navbar/index.ts @@ -133,6 +133,9 @@ export const component = defineComponentMetadata({ // const { addImportantStyle } = await import('@/core/style') // addImportantStyle(style, styleID) }, + widget: { + component: () => import('./settings/Widget.vue').then(m => m.default), + }, extraOptions: () => import('./settings/ExtraOptions.vue').then(m => m.default), plugin: { displayName: '自定义顶栏 - 功能扩展', diff --git a/registry/lib/components/style/custom-navbar/settings/Widget.vue b/registry/lib/components/style/custom-navbar/settings/Widget.vue new file mode 100644 index 000000000..286ee464e --- /dev/null +++ b/registry/lib/components/style/custom-navbar/settings/Widget.vue @@ -0,0 +1,24 @@ + + From 7c11ec1feb33d8f32e005ec3ca873235ab28a0a2 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 16:16:18 +0800 Subject: [PATCH 25/29] Support width-only images --- .../utils/image-resolution/resolution.ts | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/registry/lib/components/utils/image-resolution/resolution.ts b/registry/lib/components/utils/image-resolution/resolution.ts index 0d910a177..9838bf127 100644 --- a/registry/lib/components/utils/image-resolution/resolution.ts +++ b/registry/lib/components/utils/image-resolution/resolution.ts @@ -1,7 +1,7 @@ import { styledComponentEntry } from '@/components/styled-component' import { Options } from '.' -const resizeRegex = /@(\d+)[Ww]_(\d+)[Hh]/ +const resizeRegex = /@(\d+)[Ww](_(\d+)[Hh])?/ /** 排除 */ const excludeSelectors = ['#certify-img1', '#certify-img2'] @@ -48,16 +48,22 @@ export const imageResolution = async (dpi: number, element: HTMLElement) => { if (value.includes(',')) { return } + const match = value.match(resizeRegex) if (!match) { return } - const [, currentWidth, currentHeight] = match + const [, currentWidth, , currentHeight] = match const lastWidth = parseInt(element.getAttribute('data-resolution-width') || '0') if (parseInt(currentWidth) >= lastWidth && lastWidth !== 0) { return } - if (element.getAttribute('width') === null && element.getAttribute('height') === null) { + + if ( + element.getAttribute('width') === null && + element.getAttribute('height') === null && + currentHeight !== undefined + ) { if (widthAndHeightSelectors.some(selector => element.matches(selector))) { element.setAttribute('height', currentHeight) element.setAttribute('width', currentWidth) @@ -67,10 +73,17 @@ export const imageResolution = async (dpi: number, element: HTMLElement) => { element.setAttribute('width', currentWidth) } } - const newWidth = Math.round(dpi * parseInt(currentWidth)).toString() - const newHeight = Math.round(dpi * parseInt(currentHeight)).toString() - element.setAttribute('data-resolution-width', newWidth) - setValue(element, value.replace(resizeRegex, `@${newWidth}w_${newHeight}h`)) + + if (currentHeight !== undefined) { + const newWidth = Math.round(dpi * parseInt(currentWidth)).toString() + const newHeight = Math.round(dpi * parseInt(currentHeight)).toString() + element.setAttribute('data-resolution-width', newWidth) + setValue(element, value.replace(resizeRegex, `@${newWidth}w_${newHeight}h`)) + } else { + const newWidth = Math.round(dpi * parseInt(currentWidth)).toString() + element.setAttribute('data-resolution-width', newWidth) + setValue(element, value.replace(resizeRegex, `@${newWidth}w`)) + } } attributes(element, () => { replaceSource( From dbe99a4ee185458fefa2a357232e856d5d2b11d3 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 17:00:28 +0800 Subject: [PATCH 26/29] Add Subresource Integrity (#4896) --- .../video/download/wasm-output/utils.ts | 18 +++++++- src/client/common.meta.json | 2 +- src/core/runtime-library.ts | 42 +++++++++++++++---- webpack/cdn/github.ts | 26 +++++++++--- webpack/cdn/jsdelivr.ts | 41 ++++++++++++++---- webpack/cdn/types.ts | 18 ++++---- 6 files changed, 113 insertions(+), 34 deletions(-) diff --git a/registry/lib/plugins/video/download/wasm-output/utils.ts b/registry/lib/plugins/video/download/wasm-output/utils.ts index fb02e15ad..fe2ec33d7 100644 --- a/registry/lib/plugins/video/download/wasm-output/utils.ts +++ b/registry/lib/plugins/video/download/wasm-output/utils.ts @@ -1,6 +1,7 @@ import { Toast } from '@/core/toast' import { formatFileSize, formatPercent } from '@/core/utils/formatters' import { getOrLoad, storeNames } from './database' +import { RuntimeLibraryDefinition, RuntimeLibrary } from '@/core/runtime-library' type OnProgress = (received: number, total: number) => void @@ -56,8 +57,21 @@ export async function httpGet(url: string, onprogress: OnProgress) { return chunksAll } -export async function getCacheOrFetch(key: string, url: string, loading: OnProgress) { - return getOrLoad(storeNames.cache, key, async () => httpGet(url, loading)) +export async function getCacheOrFetch( + key: string, + library: RuntimeLibraryDefinition, + loading: OnProgress, +) { + return getOrLoad(storeNames.cache, key, async () => { + const content = await httpGet(library.url, loading) + const sha256 = await RuntimeLibrary.sha256(content) + if (sha256 !== library.sha256) { + throw new Error( + `Check integrity failed from ${library.url}, expected = ${library.sha256}, actual = ${sha256}`, + ) + } + return content + }) } export function toBlobUrl(buffer: Uint8Array, mimeType: string) { diff --git a/src/client/common.meta.json b/src/client/common.meta.json index 0c3a9889f..943e27cd3 100644 --- a/src/client/common.meta.json +++ b/src/client/common.meta.json @@ -38,7 +38,7 @@ "*" ], "require": [ - "[altCdn.library.lodash]" + "[altCdn.library.lodash.url]#sha256=[altCdn.library.lodash.sha256]" ], "icon": "[altCdn.smallLogo]", "icon64": "[altCdn.logo]" diff --git a/src/core/runtime-library.ts b/src/core/runtime-library.ts index 73f2a3140..4ba753410 100644 --- a/src/core/runtime-library.ts +++ b/src/core/runtime-library.ts @@ -5,26 +5,54 @@ import type StreamSaverType from 'streamsaver' import { monkey } from './ajax' import { meta } from './meta' +export type RuntimeLibraryDefinition = { url: string; sha256: string } export interface RuntimeLibraryConfig { - url: string + library: RuntimeLibraryDefinition getModule: (window: Window) => LibraryType } + export class RuntimeLibrary implements PromiseLike { private modulePromise: Promise constructor(public config: RuntimeLibraryConfig) {} + static async sha256(content: string | BufferSource) { + const hashBuffer = await window.crypto.subtle.digest( + 'SHA-256', + typeof content === 'string' ? new TextEncoder().encode(content) : content, + ) + const hashArray = Array.from(new Uint8Array(hashBuffer)) + const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('') + return hashHex + } + + private async checkIntegrity(content: string | BufferSource) { + const sha256 = await RuntimeLibrary.sha256(content) + if (sha256 !== this.config.library.sha256) { + throw new Error( + `[RuntimeLibrary] Check integrity failed from ${this.config.library.url}, expected = ${this.config.library.sha256}, actual = ${sha256}`, + ) + } + console.log( + `[Runtime Library] Checked integrity from ${this.config.library.url}, hash = ${sha256}`, + ) + } + async then( resolve?: (value: LibraryType) => Resolve | PromiseLike, reject?: (reason: any) => Reject | PromiseLike, ) { try { - const { url, getModule } = this.config + const { + library: { url }, + getModule, + } = this.config if (!this.modulePromise) { this.modulePromise = (async () => { console.log(`[Runtime Library] Start download from ${url}`) const code: string = await monkey({ url }) - console.log(`[Runtime Library] Downloaded from ${url} , length = ${code.length}`) + console.log(`[Runtime Library] Downloaded from ${url}, length = ${code.length}`) + await this.checkIntegrity(code) ;(function runEval() { return eval(code) // eslint-disable-next-line no-extra-bind @@ -41,18 +69,18 @@ export class RuntimeLibrary implements PromiseLike { } } export const protobufLibrary = new RuntimeLibrary({ - url: meta.compilationInfo.altCdn.library.protobuf, + library: meta.compilationInfo.altCdn.library.protobuf, getModule: window => window.protobuf, }) export const JSZipLibrary = new RuntimeLibrary({ - url: meta.compilationInfo.altCdn.library.jszip, + library: meta.compilationInfo.altCdn.library.jszip, getModule: window => window.JSZip, }) export const SortableJSLibrary = new RuntimeLibrary({ - url: meta.compilationInfo.altCdn.library.sortable, + library: meta.compilationInfo.altCdn.library.sortable, getModule: window => window.Sortable, }) export const StreamSaverLibrary = new RuntimeLibrary({ - url: meta.compilationInfo.altCdn.library.streamsaver, + library: meta.compilationInfo.altCdn.library.streamsaver, getModule: window => window.streamSaver, }) diff --git a/webpack/cdn/github.ts b/webpack/cdn/github.ts index 05872c69f..f23bf1994 100644 --- a/webpack/cdn/github.ts +++ b/webpack/cdn/github.ts @@ -10,12 +10,26 @@ export const github: CdnConfig = { stableClient: `https://${host}/${owner}/Bilibili-Evolved/master/dist/bilibili-evolved.user.js`, previewClient: `https://${host}/${owner}/Bilibili-Evolved/preview/dist/bilibili-evolved.preview.user.js`, library: { - lodash: `https://${host}/lodash/lodash/4.17.21/dist/lodash.min.js`, - protobuf: `https://${host}/protobufjs/protobuf.js/v6.10.1/dist/light/protobuf.min.js`, - jszip: `https://${host}/Stuk/jszip/v3.7.1/dist/jszip.min.js`, - sortable: `https://${host}/SortableJS/Sortable/1.14.0/Sortable.min.js`, - mdi: `https://${owner}.github.io/Bilibili-Evolved/static/mdi/mdi.css`, - streamsaver: `https://${host}/jimmywarting/StreamSaver.js/2.0.6/StreamSaver.js`, + lodash: { + url: `https://${host}/lodash/lodash/4.17.21/dist/lodash.min.js`, + sha256: 'a9705dfc47c0763380d851ab1801be6f76019f6b67e40e9b873f8b4a0603f7a9', + }, + protobuf: { + url: `https://${host}/protobufjs/protobuf.js/v6.10.1/dist/light/protobuf.min.js`, + sha256: '8978daf871b02d683ecaee371861702a6f31d0a4c52925b7db2bb1655a8bc7d1', + }, + jszip: { + url: `https://${host}/Stuk/jszip/v3.7.1/dist/jszip.min.js`, + sha256: 'c9e4a52bac18aee4f3f90d05fbca603f5b0f5bf1ce8c45e60bb4ed3a2cb2ed86', + }, + sortable: { + url: `https://${host}/SortableJS/Sortable/1.14.0/Sortable.min.js`, + sha256: '0ea5a6fbfbf5434b606878533cb7a66bcf700f0f08afe908335d0978fb63ad94', + }, + streamsaver: { + url: `https://${host}/jimmywarting/StreamSaver.js/2.0.6/StreamSaver.js`, + sha256: 'a110f78e0b092481dc372901c4d57ae50681d773bc9d55e62356f9a22f17e24b', + }, // https://github.com/the1812/Bilibili-Evolved/pull/4521#discussion_r1402084486 ffmpeg: jsDelivr.library.ffmpeg, }, diff --git a/webpack/cdn/jsdelivr.ts b/webpack/cdn/jsdelivr.ts index 3765b9774..219c8ec27 100644 --- a/webpack/cdn/jsdelivr.ts +++ b/webpack/cdn/jsdelivr.ts @@ -9,16 +9,39 @@ export const jsDelivr: CdnConfig = { stableClient: `https://${host}/gh/${owner}/Bilibili-Evolved@master/dist/bilibili-evolved.user.js`, previewClient: `https://${host}/gh/${owner}/Bilibili-Evolved@preview/dist/bilibili-evolved.preview.user.js`, library: { - lodash: `https://${host}/npm/lodash@4.17.21/lodash.min.js`, - protobuf: `https://${host}/npm/protobufjs@6.10.1/dist/light/protobuf.min.js`, - jszip: `https://${host}/npm/jszip@3.7.1/dist/jszip.min.js`, - sortable: `https://${host}/npm/sortablejs@1.14.0/Sortable.min.js`, - mdi: `https://${host}/gh/${owner}/Bilibili-Evolved@master/docs/static/mdi/mdi.css`, - streamsaver: `https://${host}/npm/streamsaver@2.0.6/StreamSaver.min.js`, + lodash: { + url: `https://${host}/npm/lodash@4.17.21/lodash.min.js`, + sha256: 'a9705dfc47c0763380d851ab1801be6f76019f6b67e40e9b873f8b4a0603f7a9', + }, + protobuf: { + url: `https://${host}/npm/protobufjs@6.10.1/dist/light/protobuf.min.js`, + sha256: '8978daf871b02d683ecaee371861702a6f31d0a4c52925b7db2bb1655a8bc7d1', + }, + jszip: { + url: `https://${host}/npm/jszip@3.7.1/dist/jszip.min.js`, + sha256: 'c9e4a52bac18aee4f3f90d05fbca603f5b0f5bf1ce8c45e60bb4ed3a2cb2ed86', + }, + sortable: { + url: `https://${host}/npm/sortablejs@1.14.0/Sortable.min.js`, + sha256: '0ea5a6fbfbf5434b606878533cb7a66bcf700f0f08afe908335d0978fb63ad94', + }, + streamsaver: { + url: `https://${host}/npm/streamsaver@2.0.6/StreamSaver.min.js`, + sha256: '64f465e51e5992be894c5d42330b781544eda5462069fe6be4c7421f02d28c92', + }, ffmpeg: { - worker: `https://${host}/npm/@ffmpeg/ffmpeg@0.12.4/dist/umd/814.ffmpeg.js`, - core: `https://${host}/npm/@ffmpeg/core@0.12.4/dist/umd/ffmpeg-core.js`, - wasm: `https://${host}/npm/@ffmpeg/core@0.12.4/dist/umd/ffmpeg-core.wasm`, + worker: { + url: `https://${host}/npm/@ffmpeg/ffmpeg@0.12.4/dist/umd/814.ffmpeg.js`, + sha256: 'baf19437171b1bccae4416e4da69fb40455b8e67142f79c8ec9da36b1de7fd8a', + }, + core: { + url: `https://${host}/npm/@ffmpeg/core@0.12.4/dist/umd/ffmpeg-core.js`, + sha256: '6af6b8cd8c878dec6f61f3cd6be16e88f9391dd265e51f20afea5c0f718bfba0', + }, + wasm: { + url: `https://${host}/npm/@ffmpeg/core@0.12.4/dist/umd/ffmpeg-core.wasm`, + sha256: '925bd7ef35d4e0f715254cd650f4cfc68c4ec6ecebf293face72b92da904ddda', + }, }, }, smallLogo: `https://${host}/gh/${owner}/Bilibili-Evolved@preview/images/logo-small.png`, diff --git a/webpack/cdn/types.ts b/webpack/cdn/types.ts index 841d97d4d..5860ee74e 100644 --- a/webpack/cdn/types.ts +++ b/webpack/cdn/types.ts @@ -1,3 +1,4 @@ +export type ExternalLibrary = { url: string; sha256: string } export interface CdnConfig { name: string owner: string @@ -5,16 +6,15 @@ export interface CdnConfig { stableClient: string previewClient: string library: { - lodash: string - protobuf: string - jszip: string - sortable: string - mdi: string - streamsaver: string + lodash: ExternalLibrary + protobuf: ExternalLibrary + jszip: ExternalLibrary + sortable: ExternalLibrary + streamsaver: ExternalLibrary ffmpeg: { - worker: string - core: string - wasm: string + worker: ExternalLibrary + core: ExternalLibrary + wasm: ExternalLibrary } } smallLogo: string From 392f696cdc32517a49f1e1e12a1d0279367cca42 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 21:02:01 +0800 Subject: [PATCH 27/29] Add original images for articles (#2868) --- .../utils/image-resolution/index.ts | 4 ++ .../utils/image-resolution/resolution.ts | 62 +++++++++++++++---- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/registry/lib/components/utils/image-resolution/index.ts b/registry/lib/components/utils/image-resolution/index.ts index f42d2bc44..8158ecf56 100644 --- a/registry/lib/components/utils/image-resolution/index.ts +++ b/registry/lib/components/utils/image-resolution/index.ts @@ -11,6 +11,10 @@ const options = defineOptionsMetadata({ defaultValue: 'auto', hidden: true, }, + originalImageInArticles: { + displayName: '在专栏中请求原图', + defaultValue: false, + }, }) export type Options = OptionsOfMetadata diff --git a/registry/lib/components/utils/image-resolution/resolution.ts b/registry/lib/components/utils/image-resolution/resolution.ts index 9838bf127..bdc04d042 100644 --- a/registry/lib/components/utils/image-resolution/resolution.ts +++ b/registry/lib/components/utils/image-resolution/resolution.ts @@ -17,6 +17,7 @@ const widthAndHeightSelectors = [ // https://github.com/the1812/Bilibili-Evolved/issues/4480 '.logo-img', ] +const originalImageInArticlesSelectors = ['.article-detail .article-content img'] const walk = (rootElement: Node, action: (node: HTMLElement) => void) => { const walker = document.createNodeIterator(rootElement, NodeFilter.SHOW_ELEMENT) @@ -26,12 +27,21 @@ const walk = (rootElement: Node, action: (node: HTMLElement) => void) => { node = walker.nextNode() } } + +interface ImageResolutionHandler { + getWidth: (width: number, element: HTMLElement) => number + getHeight: (height: number, element: HTMLElement) => number +} + /** * 从开始元素`element`向下遍历所有子节点, 更换其中的图片URL至目标DPI * @param dpi 目标DPI * @param element 开始元素 */ -export const imageResolution = async (dpi: number, element: HTMLElement) => { +export const imageResolution = async ( + element: HTMLElement, + resolutionHandler: ImageResolutionHandler, +) => { const { attributes } = await import('@/core/observer') const replaceSource = ( getValue: (e: HTMLElement) => string | null, @@ -74,15 +84,24 @@ export const imageResolution = async (dpi: number, element: HTMLElement) => { } } + const getReplacedValue = (newWidth: number, newHeight?: number) => { + if (newWidth === Infinity || newHeight === Infinity) { + return value.replace(resizeRegex, '@') + } + if (newHeight === undefined) { + return value.replace(resizeRegex, `@${newWidth}w`) + } + return value.replace(resizeRegex, `@${newWidth}w_${newHeight}h`) + } if (currentHeight !== undefined) { - const newWidth = Math.round(dpi * parseInt(currentWidth)).toString() - const newHeight = Math.round(dpi * parseInt(currentHeight)).toString() - element.setAttribute('data-resolution-width', newWidth) - setValue(element, value.replace(resizeRegex, `@${newWidth}w_${newHeight}h`)) + const newWidth = resolutionHandler.getWidth(parseInt(currentWidth), element) + const newHeight = resolutionHandler.getHeight(parseInt(currentHeight), element) + element.setAttribute('data-resolution-width', newWidth.toString()) + setValue(element, getReplacedValue(newWidth, newHeight)) } else { - const newWidth = Math.round(dpi * parseInt(currentWidth)).toString() - element.setAttribute('data-resolution-width', newWidth) - setValue(element, value.replace(resizeRegex, `@${newWidth}w`)) + const newWidth = resolutionHandler.getWidth(parseInt(currentWidth), element) + element.setAttribute('data-resolution-width', newWidth.toString()) + setValue(element, getReplacedValue(newWidth)) } } attributes(element, () => { @@ -108,14 +127,35 @@ export const startResolution = styledComponentEntry( settings.options.scale === 'auto' ? window.devicePixelRatio : parseFloat(settings.options.scale) - walk(document.body, it => imageResolution(dpi, it)) + const handleResolution: ImageResolutionHandler = { + getWidth: (currentWidth, element) => { + if ( + settings.options.originalImageInArticles && + originalImageInArticlesSelectors.some(selector => element.matches(selector)) + ) { + return Infinity + } + return Math.round(dpi * currentWidth) + }, + getHeight: (currentHeight, element) => { + if ( + settings.options.originalImageInArticles && + originalImageInArticlesSelectors.some(selector => element.matches(selector)) + ) { + return Infinity + } + return Math.round(dpi * currentHeight) + }, + } + + walk(document.body, it => imageResolution(it, handleResolution)) allMutations(records => { records.forEach(record => record.addedNodes.forEach(node => { if (node instanceof HTMLElement) { - imageResolution(dpi, node) + imageResolution(node, handleResolution) if (node.nodeName.toUpperCase() !== 'IMG') { - walk(node, it => imageResolution(dpi, it)) + walk(node, it => imageResolution(it, handleResolution)) } } }), From 00c60bf051e7661e0c3f1ed9ec2350a47bd3adfe Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 21:20:17 +0800 Subject: [PATCH 28/29] Improve styles for low width (#4895) --- .../live/chat-panel-fit/chat-panel-fit.scss | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/registry/lib/components/live/chat-panel-fit/chat-panel-fit.scss b/registry/lib/components/live/chat-panel-fit/chat-panel-fit.scss index a07c769cd..f3d150d8d 100644 --- a/registry/lib/components/live/chat-panel-fit/chat-panel-fit.scss +++ b/registry/lib/components/live/chat-panel-fit/chat-panel-fit.scss @@ -1,10 +1,30 @@ .player-full-win:not(.hide-aside-area) { .live-room-app { .aside-area { + container-name: aside-area; + container-type: size; width: var(--live-chat-panel-width, 302px) !important; } .player-section { width: calc(100% - var(--live-chat-panel-width, 302px)) !important; } + @container aside-area (max-width: 290px) { + .control-panel-icon-row-new .icon-left-part-new { + .super-chat, + .like-btn { + width: 32px; + &-icon { + margin-right: 0 !important; + } + &-text { + display: none !important; + } + } + } + .chat-input-ctnr-new .medal-section { + min-width: 0 !important; + max-width: 0 !important; + } + } } } From b512fc6b4edbdd99e467b30a1c7be66ed8a58b70 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 8 Sep 2024 23:19:50 +0800 Subject: [PATCH 29/29] Update docs --- doc/features/features.json | 2 +- doc/features/features.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/features/features.json b/doc/features/features.json index 8d1829830..176fc61fe 100644 --- a/doc/features/features.json +++ b/doc/features/features.json @@ -707,7 +707,7 @@ "type": "component", "name": "unescapeDanmaku", "displayName": "弹幕转义", - "description": "将弹幕中的 `\\n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠.\r\n", + "description": "将弹幕中的 `\\n` 或 `/n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠.\r\n", "fullRelativePath": "../../registry/dist/components/video/danmaku/unescape.js", "fullAbsolutePath": "registry/dist/components/video/danmaku/unescape.js" }, diff --git a/doc/features/features.md b/doc/features/features.md index ee4dcfa8b..570495ddd 100644 --- a/doc/features/features.md +++ b/doc/features/features.md @@ -969,7 +969,7 @@ by [@kdxcxs](https://github.com/kdxcxs) **GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/danmaku/unescape.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/danmaku/unescape.js) -将弹幕中的 `\n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠. +将弹幕中的 `\n` 或 `/n` 替换为真实的换行, 注意这可能导致原先不重叠的弹幕发生重叠. ### [视频页默认定位](../../registry/dist/components/video/default-location.js) `videoDefaultLocation`