From f408fb1fdaf7b452b3cd82ab67daa9bae10f2122 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Sun, 29 Jan 2023 11:39:46 +0800 Subject: [PATCH 01/52] Fix lint errors/warnings --- registry/lib/components/utils/import-series/logic.ts | 6 +++--- .../components/video/player/extend-speed/component.ts | 1 + src/components/i18n/dom-translator.ts | 10 ++++++++++ src/core/utils/index.ts | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/registry/lib/components/utils/import-series/logic.ts b/registry/lib/components/utils/import-series/logic.ts index ac4786738..cf9f4cc6b 100644 --- a/registry/lib/components/utils/import-series/logic.ts +++ b/registry/lib/components/utils/import-series/logic.ts @@ -19,7 +19,7 @@ const importSeries = async (sid, uid, csrf) => { // 创建收藏夹,获取新收藏夹id let favId = 0 - while (true) { + for (;;) { const response = await fetch('https://api.bilibili.com/x/v3/fav/folder/add', { method: 'POST', credentials: 'include', @@ -43,7 +43,7 @@ const importSeries = async (sid, uid, csrf) => { for (let i = 0; i < seriesVideos.length; i++) { // 做个延迟,防止太快而遭服务器拒绝 await delay(500) - while (true) { + for (;;) { const response = await fetch('https://api.bilibili.com/x/v3/fav/resource/deal', { method: 'POST', credentials: 'include', @@ -72,7 +72,7 @@ const importSeries = async (sid, uid, csrf) => { } const importCollection = async (sid, csrf) => { - while (true) { + for (;;) { const response = await fetch('https://api.bilibili.com/x/v3/fav/season/fav', { method: 'POST', credentials: 'include', diff --git a/registry/lib/components/video/player/extend-speed/component.ts b/registry/lib/components/video/player/extend-speed/component.ts index d4bc9c82c..adf92751a 100644 --- a/registry/lib/components/video/player/extend-speed/component.ts +++ b/registry/lib/components/video/player/extend-speed/component.ts @@ -444,6 +444,7 @@ export class ExtendSpeedComponent extends EntrySpeedComponent { setTimeout(() => this.forceUpdateStyle(value)) } + // eslint-disable-next-line class-methods-use-this protected readonly filterNativeSpeed = () => ({ subscribe, next }: PublishContext) => { diff --git a/src/components/i18n/dom-translator.ts b/src/components/i18n/dom-translator.ts index 57d8c5675..9b95f4ec8 100644 --- a/src/components/i18n/dom-translator.ts +++ b/src/components/i18n/dom-translator.ts @@ -12,11 +12,15 @@ export class Translator { static map: Map static regex: [RegExp, string][] + // eslint-disable-next-line class-methods-use-this protected accepts = (node: Node) => node.nodeType === Node.ELEMENT_NODE + // eslint-disable-next-line class-methods-use-this protected getValue = (node: Node) => node.nodeValue + // eslint-disable-next-line class-methods-use-this protected setValue = (node: Node, value: string) => { node.nodeValue = value } + // eslint-disable-next-line class-methods-use-this protected getElement = (node: Node) => node as Element translate(node: Node) { let value = this.getValue(node) @@ -99,17 +103,23 @@ export class Translator { } } export class TextNodeTranslator extends Translator { + // eslint-disable-next-line class-methods-use-this accepts = (node: Node) => node.nodeType === Node.TEXT_NODE + // eslint-disable-next-line class-methods-use-this getElement = (node: Node) => node.parentElement } export class TitleTranslator extends Translator { + // eslint-disable-next-line class-methods-use-this getValue = (node: Node) => (node as Element).getAttribute('title') + // eslint-disable-next-line class-methods-use-this setValue = (node: Node, value: string) => { ;(node as Element).setAttribute('title', value) } } export class PlaceholderTranslator extends Translator { + // eslint-disable-next-line class-methods-use-this getValue = (node: Node) => (node as Element).getAttribute('placeholder') + // eslint-disable-next-line class-methods-use-this setValue = (node: Node, value: string) => { ;(node as Element).setAttribute('placeholder', value) } diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 270e5e04d..babc4e035 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -407,6 +407,7 @@ export class DoubleClickEvent { singleClickHandler: (e: MouseEvent) => void = none private clickedOnce = false + // eslint-disable-next-line class-methods-use-this private readonly stopPropagationHandler = (e: MouseEvent) => { e.stopImmediatePropagation() } From f2f9eb9a3e1ac8dcad09d64ae84afa3496f0a6ab Mon Sep 17 00:00:00 2001 From: JLoeve <34429322+LonelySteve@users.noreply.github.com> Date: Sat, 4 Feb 2023 22:53:11 +0800 Subject: [PATCH 02/52] feat(bisector): Add bisector --- src/components/bisector/DialogContent.vue | 56 +++++ src/components/bisector/DialogTitle.vue | 43 ++++ .../bisector/ResultToastContent.vue | 54 +++++ src/components/bisector/api.ts | 200 ++++++++++++++++++ src/components/bisector/bisect.ts | 70 ++++++ src/components/bisector/index.ts | 45 ++++ src/components/bisector/options.ts | 31 +++ src/components/built-in-components.ts | 2 + src/components/types.ts | 3 + src/components/user-component.ts | 15 ++ src/core/dialog/index.ts | 2 +- 11 files changed, 520 insertions(+), 1 deletion(-) create mode 100644 src/components/bisector/DialogContent.vue create mode 100644 src/components/bisector/DialogTitle.vue create mode 100644 src/components/bisector/ResultToastContent.vue create mode 100644 src/components/bisector/api.ts create mode 100644 src/components/bisector/bisect.ts create mode 100644 src/components/bisector/index.ts create mode 100644 src/components/bisector/options.ts diff --git a/src/components/bisector/DialogContent.vue b/src/components/bisector/DialogContent.vue new file mode 100644 index 000000000..9ef26d981 --- /dev/null +++ b/src/components/bisector/DialogContent.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/components/bisector/DialogTitle.vue b/src/components/bisector/DialogTitle.vue new file mode 100644 index 000000000..2ae4acad4 --- /dev/null +++ b/src/components/bisector/DialogTitle.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/components/bisector/ResultToastContent.vue b/src/components/bisector/ResultToastContent.vue new file mode 100644 index 000000000..09b3fc143 --- /dev/null +++ b/src/components/bisector/ResultToastContent.vue @@ -0,0 +1,54 @@ + + + diff --git a/src/components/bisector/api.ts b/src/components/bisector/api.ts new file mode 100644 index 000000000..d7f91f322 --- /dev/null +++ b/src/components/bisector/api.ts @@ -0,0 +1,200 @@ +import { DialogInstance, showDialog } from '@/core/dialog' +import type { Settings } from '@/core/settings/types' +import { Toast } from '@/core/toast' +import { mountVueComponent } from '@/core/utils' +import { useScopedConsole } from '@/core/utils/log' +import type { RecordValue } from '../types' +import type { BisectNext } from './bisect' +import { bisect } from './bisect' +import { BisectorOptions } from './options' +import ResultToastContent from './ResultToastContent.vue' + +type UserComponent = RecordValue + +let bisectorOptions: BisectorOptions +let scopedConsole: ReturnType +let bisectorGenerator: ReturnType +let groupedComponents: Awaited> +let dialog: DialogInstance + +export const setOptions = (options: BisectorOptions) => { + if (!bisectorOptions) { + bisectorOptions = options + } else { + Object.assign(bisectorOptions, options) + } +} + +export const setConsole = (console: ReturnType) => { + scopedConsole = console +} + +const classifyComponents = async () => { + const { settings } = await import('@/core/settings') + + const { userComponents } = settings + const configurableUserComponents = lodash.pickBy( + userComponents, + v => v.metadata.configurable || true, + ) + const { targetComponents, keepDisabledComponents, keepEnabledComponents } = lodash.transform( + configurableUserComponents, + (result, v, k) => { + if (bisectorOptions.keepEnabledComponents?.includes(k)) { + result.keepEnabledComponents.push(v) + return + } + if (bisectorOptions.keepDisabledComponents?.includes(k)) { + result.keepDisabledComponents.push(v) + return + } + result.targetComponents.push(v) + }, + { + targetComponents: [] as UserComponent[], + keepDisabledComponents: [] as UserComponent[], + keepEnabledComponents: [] as UserComponent[], + }, + ) + + return { + userComponents, + configurableUserComponents, + targetComponents, + keepDisabledComponents, + keepEnabledComponents, + } +} + +const setComponentsEnabled = (components: UserComponent[], enabled: boolean) => + components.forEach(component => (component.settings.enabled = enabled)) + +const getComponentNames = (components: UserComponent[]) => + components + .map(component => `${component.metadata.displayName}(${component.metadata.name})`) + .join(', ') || '无' + +export const isRecover = () => !lodash.isEmpty(bisectorOptions.bisectInitialState) + +export const stop = async () => { + scopedConsole?.log('stop - 准备停止组件二等分') + dialog?.close() + const { configurableUserComponents } = await classifyComponents() + const unmatchedComponentNames = [] + for (const [componentName, componentSettings] of Object.entries(configurableUserComponents)) { + const originalStatus = bisectorOptions.originalComponentEnableState?.[componentName] + if (originalStatus == null) { + unmatchedComponentNames.push(componentName) + continue + } + componentSettings.settings.enabled = originalStatus + } + if (unmatchedComponentNames.length) { + scopedConsole?.warn( + `stop - 部分组件未能还原状态:${getComponentNames(unmatchedComponentNames)}`, + ) + } + scopedConsole?.log('stop - 清理状态') + bisectorGenerator = null + bisectorOptions.bisectInitialState = {} + scopedConsole?.log('stop - 重载页面') + location.reload() +} + +export const next = async (seeingBad?: boolean, autoReload?: boolean) => { + dialog?.close() + scopedConsole?.log( + `next - 当前工作状态:${ + // eslint-disable-next-line no-nested-ternary + seeingBad == null ? '未知' : seeingBad ? '异常' : '正常' + }`, + ) + const { done, value } = bisectorGenerator.next(seeingBad) as unknown as { + done: boolean + value: BisectNext | UserComponent + } + if (done) { + const elementId = `bisector-result-toast-content-${Math.floor( + Math.random() * (Number.MAX_SAFE_INTEGER + 1), + )}` + Toast.info(/* html */ `
`, '二等分结果') + setTimeout(() => { + const vm = mountVueComponent<{ userComponent: UserComponent }>( + ResultToastContent, + `#${elementId}`, + ) + vm.userComponent = value as UserComponent + vm.$on('restore', () => { + stop() + }) + }) + } else { + const { slice, low, high } = value as BisectNext + const needEnabled = slice + const needDisabled = lodash.difference(groupedComponents.targetComponents, slice) + bisectorOptions.bisectInitialState = { low, high } + scopedConsole?.log(`next - 关闭组件:${getComponentNames(needDisabled)}`) + scopedConsole?.log(`next - 开启组件:${getComponentNames(needEnabled)}`) + setComponentsEnabled(needDisabled, false) + setComponentsEnabled(needEnabled, true) + if (autoReload) { + scopedConsole?.log('next - 重载页面') + location.reload() + } + } + return { done, value } +} + +export const recover = async () => { + scopedConsole?.log('recover - 准备恢复组件二等分') + groupedComponents = await classifyComponents() + const { targetComponents, keepDisabledComponents, keepEnabledComponents } = groupedComponents + setComponentsEnabled(keepEnabledComponents, true) + setComponentsEnabled(keepDisabledComponents, false) + scopedConsole?.log(`recover - 保持关闭组件:${getComponentNames(keepDisabledComponents)}`) + scopedConsole?.log(`recover - 保持开启组件:${getComponentNames(keepEnabledComponents)}`) + scopedConsole?.log(`recover - 全部目标组件:${getComponentNames(targetComponents)}`) + bisectorGenerator = bisect(targetComponents, bisectorOptions.bisectInitialState) + const { done, value } = await next() + if (!done) { + const { rouge } = value as BisectNext + dialog = showDialog({ + title: () => import('./DialogTitle.vue'), + content: () => import('./DialogContent.vue'), + contentProps: { + rouge, + onGood: () => next(false, true), + onBad: () => next(true, true), + onAbort: () => stop(), + }, + }) + } +} + +export const start = async () => { + if (isRecover()) { + await recover() + return + } + scopedConsole?.log('start - 准备开始组件二等分') + groupedComponents = await classifyComponents() + const { + configurableUserComponents, + targetComponents, + keepDisabledComponents, + keepEnabledComponents, + } = groupedComponents + scopedConsole?.log('start - 保存组件初始启用状态') + bisectorOptions.originalComponentEnableState = lodash.mapValues( + configurableUserComponents, + v => v.settings.enabled, + ) + setComponentsEnabled(targetComponents, true) + setComponentsEnabled(keepEnabledComponents, true) + setComponentsEnabled(keepDisabledComponents, false) + scopedConsole?.log(`start - 保持关闭组件:${getComponentNames(keepDisabledComponents)}`) + scopedConsole?.log(`start - 保持开启组件:${getComponentNames(keepEnabledComponents)}`) + scopedConsole?.log(`start - 启用全部目标组件:${getComponentNames(targetComponents)}`) + bisectorGenerator = bisect(targetComponents, bisectorOptions.bisectInitialState) + await next(undefined, true) +} diff --git a/src/components/bisector/bisect.ts b/src/components/bisector/bisect.ts new file mode 100644 index 000000000..e7d8e1284 --- /dev/null +++ b/src/components/bisector/bisect.ts @@ -0,0 +1,70 @@ +/* eslint-disable no-bitwise */ + +export interface BisectNext { + low: number + high: number + mid: number + slice: O[] + rouge: number +} + +export interface InitialState { + low?: number + high?: number +} + +export function* bisectLeft(data: readonly O[], initialState?: InitialState) { + let low = initialState?.low ?? 0 + let high = initialState?.high ?? data.length + let mid = (low + high) >>> 1 + + while (true) { + const seeingBad = yield ({ + low, + high, + mid, + slice: data.slice(low, mid), + rouge: ~~Math.log2(high - low), + } as BisectNext) || false + + if (seeingBad) { + high = mid + } else { + low = mid + } + if (low + 1 < high) { + mid = (low + high) >>> 1 + } else { + return data[low] + } + } +} + +export function* bisectRight(data: readonly O[], initialState?: InitialState) { + let low = initialState?.low ?? 0 + let high = initialState?.high ?? data.length + let mid = (low + high) >>> 1 + + while (true) { + const seeingBad = yield ({ + low, + high, + mid, + slice: data.slice(mid, high), + rouge: ~~Math.log2(high - low), + } as BisectNext) || false + + if (seeingBad) { + low = mid + } else { + high = mid + } + if (low + 1 < high) { + mid = (low + high) >>> 1 + } else { + return data[low] + } + } +} + +export const bisect = bisectLeft diff --git a/src/components/bisector/index.ts b/src/components/bisector/index.ts new file mode 100644 index 000000000..cb69b857d --- /dev/null +++ b/src/components/bisector/index.ts @@ -0,0 +1,45 @@ +import { defineComponentMetadata } from '@/components/define' +import { bisectorOptionsMetadata } from './options' +import { LifeCycleEventTypes } from '@/core/life-cycle' +import { componentsTags } from '@/components/types' +import * as bisector from './api' +import { useScopedConsole } from '@/core/utils/log' +import type { LaunchBarActionProvider } from '../launch-bar/launch-bar-action' + +export const component = defineComponentMetadata({ + name: 'bisector', + displayName: '组件二等分', + tags: [componentsTags.general, componentsTags.utils], + hidden: true, + configurable: false, + entry: async ({ settings: { options } }) => { + bisector.setOptions(options) + bisector.setConsole(useScopedConsole('组件二等分')) + unsafeWindow.addEventListener(LifeCycleEventTypes.ComponentsLoaded, () => { + if (bisector.isRecover()) { + bisector.recover() + } + }) + }, + options: bisectorOptionsMetadata, + plugin: { + displayName: '组件二等分 - 功能扩展', + setup: ({ addData }) => { + addData('launchBar.actions', (providers: LaunchBarActionProvider[]) => { + providers.push({ + name: 'bisector-start', + getActions: async () => [ + { + name: '开始/继续组件二等分', + description: 'Start/Continue component bisection', + icon: 'mdi-view-split-horizontal', + action: async () => { + await bisector.start() + }, + }, + ], + }) + }) + }, + }, +}) diff --git a/src/components/bisector/options.ts b/src/components/bisector/options.ts new file mode 100644 index 000000000..d96d8342c --- /dev/null +++ b/src/components/bisector/options.ts @@ -0,0 +1,31 @@ +import { defineOptionsMetadata, OptionsOfMetadata } from '@/components/define' +import { getComponentSettings } from '@/core/settings' +import type { InitialState } from './bisect' + +export const bisectorOptionsMetadata = defineOptionsMetadata({ + // 原始的组件启用状态 + originalComponentEnableState: { + defaultValue: {} as Record, + hidden: true, + }, + // 保持禁用状态的组件内部名称数组 + keepDisabledComponents: { + defaultValue: [] as string[], + hidden: true, + }, + // 保持启用状态的组件内部名称数组 + keepEnabledComponents: { + defaultValue: [] as string[], + hidden: true, + }, + // bisect 生成器的初始状态 + bisectInitialState: { + defaultValue: {} as Partial, + hidden: true, + }, +}) + +export const getBisectorOptions = () => + getComponentSettings>('bisector').options + +export type BisectorOptions = ReturnType diff --git a/src/components/built-in-components.ts b/src/components/built-in-components.ts index e9a0b98da..1dd47ed85 100644 --- a/src/components/built-in-components.ts +++ b/src/components/built-in-components.ts @@ -4,6 +4,7 @@ import { component as LaunchBar } from './launch-bar' import { component as I18n } from './i18n' import { component as AutoUpdate } from './auto-update' import { component as NotifyNewVersion } from './notify-new-version' +import { component as Bisector } from './bisector' export const getBuiltInComponents = (): ComponentMetadata[] => [ SettingsPanel, @@ -11,6 +12,7 @@ export const getBuiltInComponents = (): ComponentMetadata[] => [ I18n, AutoUpdate, NotifyNewVersion, + Bisector, ] export const isBuiltInComponent = (name: string) => diff --git a/src/components/types.ts b/src/components/types.ts index c3b7c411a..38261f968 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -216,3 +216,6 @@ export interface ComponentMetadata /** 用户组件的非函数基本信息, 用于直接保存为 JSON */ export type UserComponentMetadata = Omit + +/** 推断 Record 的 Value 类型 */ +export type RecordValue = R extends Record ? V : never diff --git a/src/components/user-component.ts b/src/components/user-component.ts index d2c81f969..b783c708d 100644 --- a/src/components/user-component.ts +++ b/src/components/user-component.ts @@ -1,6 +1,8 @@ import { componentToSettings } from '@/core/settings' import { isBuiltInComponent } from './built-in-components' import { ComponentMetadata, componentsMap } from './component' +import * as bisector from './bisector/api' +import { BisectorOptions } from './bisector/options' /** * 安装自定义组件 @@ -130,3 +132,16 @@ export const toggleComponent = async (nameOrDisplayName: string) => { const { displayName } = userComponent.metadata return `已${enabled ? '开启' : '关闭'}组件'${displayName}', 可能需要刷新后才能生效` } + +/** + * 二等分自定义组件的开关状态 + * + * @param options 二等分选项 + * @returns + */ +export const bisectComponent = async (options?: BisectorOptions) => { + if (options) { + bisector.setOptions(options) + } + return bisector +} diff --git a/src/core/dialog/index.ts b/src/core/dialog/index.ts index b7c160a6f..8c21794a1 100644 --- a/src/core/dialog/index.ts +++ b/src/core/dialog/index.ts @@ -10,7 +10,7 @@ export interface DialogInputs { } export interface DialogInstance extends Required { open: boolean - close: Promise + close(): Promise closeListeners: (() => void)[] } export const showDialog = (inputs: DialogInputs) => { From de541ec953617f2bcb4f84a033d30a9365ebdf13 Mon Sep 17 00:00:00 2001 From: JLoeve <34429322+LonelySteve@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:58:53 +0800 Subject: [PATCH 03/52] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=9C=AA=E8=83=BD=E8=BF=98=E5=8E=9F=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E5=BC=82=E5=B8=B8=EF=BC=8C=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E4=BA=8C=E7=AD=89=E5=88=86=E7=BB=93=E6=9E=9C=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=90=8E=E7=9A=84=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/bisector/api.ts | 50 +++++++++++++------------- src/components/bisector/bisect.ts | 60 +++++++++++++++++++++---------- src/core/utils/index.ts | 8 +++++ 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/components/bisector/api.ts b/src/components/bisector/api.ts index d7f91f322..6e650fcf4 100644 --- a/src/components/bisector/api.ts +++ b/src/components/bisector/api.ts @@ -1,10 +1,10 @@ import { DialogInstance, showDialog } from '@/core/dialog' import type { Settings } from '@/core/settings/types' import { Toast } from '@/core/toast' -import { mountVueComponent } from '@/core/utils' +import { getRandomId, mountVueComponent, sleep } from '@/core/utils' import { useScopedConsole } from '@/core/utils/log' import type { RecordValue } from '../types' -import type { BisectNext } from './bisect' +import type { BisectNext, BisectReturn } from './bisect' import { bisect } from './bisect' import { BisectorOptions } from './options' import ResultToastContent from './ResultToastContent.vue' @@ -13,7 +13,7 @@ type UserComponent = RecordValue let bisectorOptions: BisectorOptions let scopedConsole: ReturnType -let bisectorGenerator: ReturnType +let bisectorGenerator: Generator, BisectReturn> let groupedComponents: Awaited> let dialog: DialogInstance @@ -80,23 +80,25 @@ export const stop = async () => { scopedConsole?.log('stop - 准备停止组件二等分') dialog?.close() const { configurableUserComponents } = await classifyComponents() - const unmatchedComponentNames = [] + const unmatchedComponents: UserComponent[] = [] for (const [componentName, componentSettings] of Object.entries(configurableUserComponents)) { const originalStatus = bisectorOptions.originalComponentEnableState?.[componentName] if (originalStatus == null) { - unmatchedComponentNames.push(componentName) + unmatchedComponents.push(componentSettings) continue } componentSettings.settings.enabled = originalStatus } - if (unmatchedComponentNames.length) { - scopedConsole?.warn( - `stop - 部分组件未能还原状态:${getComponentNames(unmatchedComponentNames)}`, - ) + if (unmatchedComponents.length) { + const msg = `部分组件未能还原状态:${getComponentNames(unmatchedComponents)}` + scopedConsole?.warn(`stop - ${msg}`) + Toast.error(msg, '组件二等分') + await sleep(3e3) } scopedConsole?.log('stop - 清理状态') bisectorGenerator = null bisectorOptions.bisectInitialState = {} + bisectorOptions.originalComponentEnableState = {} scopedConsole?.log('stop - 重载页面') location.reload() } @@ -109,24 +111,20 @@ export const next = async (seeingBad?: boolean, autoReload?: boolean) => { seeingBad == null ? '未知' : seeingBad ? '异常' : '正常' }`, ) - const { done, value } = bisectorGenerator.next(seeingBad) as unknown as { - done: boolean - value: BisectNext | UserComponent - } + const { done, value } = bisectorGenerator.next(seeingBad) if (done) { - const elementId = `bisector-result-toast-content-${Math.floor( - Math.random() * (Number.MAX_SAFE_INTEGER + 1), - )}` - Toast.info(/* html */ `
`, '二等分结果') - setTimeout(() => { - const vm = mountVueComponent<{ userComponent: UserComponent }>( - ResultToastContent, - `#${elementId}`, - ) - vm.userComponent = value as UserComponent - vm.$on('restore', () => { - stop() - }) + const { low, high } = value + bisectorOptions.bisectInitialState = { low, high } + const elementId = `bisector-result-toast-content-${getRandomId()}` + Toast.info(/* html */ `
`, '组件二等分结果') + await sleep() + const vm = mountVueComponent<{ userComponent: UserComponent }>( + ResultToastContent, + `#${elementId}`, + ) + vm.userComponent = value.target + vm.$on('restore', () => { + stop() }) } else { const { slice, low, high } = value as BisectNext diff --git a/src/components/bisector/bisect.ts b/src/components/bisector/bisect.ts index e7d8e1284..017bf8455 100644 --- a/src/components/bisector/bisect.ts +++ b/src/components/bisector/bisect.ts @@ -8,62 +8,84 @@ export interface BisectNext { rouge: number } +export interface BisectReturn extends BisectNext { + target: O +} + export interface InitialState { low?: number high?: number } -export function* bisectLeft(data: readonly O[], initialState?: InitialState) { +export function* bisectLeft( + data: readonly O[], + initialState?: InitialState, +): Generator, BisectReturn> { let low = initialState?.low ?? 0 let high = initialState?.high ?? data.length - let mid = (low + high) >>> 1 + let mid: number - while (true) { - const seeingBad = yield ({ + while (low + 1 < high) { + mid = (low + high) >>> 1 + + const seeingBad = yield { low, high, mid, slice: data.slice(low, mid), rouge: ~~Math.log2(high - low), - } as BisectNext) || false + } if (seeingBad) { high = mid } else { low = mid } - if (low + 1 < high) { - mid = (low + high) >>> 1 - } else { - return data[low] - } + } + + return { + low, + high, + mid, + slice: data.slice(low, mid), + rouge: ~~Math.log2(high - low), + target: data[low], } } -export function* bisectRight(data: readonly O[], initialState?: InitialState) { +export function* bisectRight( + data: readonly O[], + initialState?: InitialState, +): Generator, BisectReturn> { let low = initialState?.low ?? 0 let high = initialState?.high ?? data.length let mid = (low + high) >>> 1 - while (true) { - const seeingBad = yield ({ + while (low + 1 < high) { + mid = (low + high) >>> 1 + + const seeingBad = yield { low, high, mid, slice: data.slice(mid, high), rouge: ~~Math.log2(high - low), - } as BisectNext) || false + } if (seeingBad) { low = mid } else { high = mid } - if (low + 1 < high) { - mid = (low + high) >>> 1 - } else { - return data[low] - } + } + + return { + low, + high, + mid, + slice: data.slice(low, mid), + rouge: ~~Math.log2(high - low), + target: data[low], } } diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 270e5e04d..797f88631 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -634,3 +634,11 @@ export const getRandomId = (length = 8) => { .join('') .substring(0, length) } + +/** + * 异步延时指定毫秒数 + * + * @param ms 传递给 setTimeout 的第二个参数,表示延时时间 + * @returns + */ +export const sleep = (ms?: number) => new Promise(resolve => setTimeout(resolve, ms)) From e7288c8e1f6a89a2a58bb0dcca3c5b3a7896ec4f Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 20 Feb 2023 02:59:04 +0800 Subject: [PATCH 04/52] Change load-feature-code.ts --- src/core/external-input/load-feature-code.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/external-input/load-feature-code.ts b/src/core/external-input/load-feature-code.ts index 7e926330a..95ef0d805 100644 --- a/src/core/external-input/load-feature-code.ts +++ b/src/core/external-input/load-feature-code.ts @@ -1,5 +1,8 @@ export class LoadFeatureCodeError extends Error {} +/** + * feature 代码运行沙箱 + */ interface CodeSandbox { /** * 在沙箱中执行代码 @@ -15,11 +18,11 @@ interface CodeSandbox { } /** - * 获取代码运行沙箱 + * 创建 feature 代码的运行沙箱 * - * @returns 一个函数:接受代码,返回。 + * @returns 一个 `CodeSandbox`。 */ -const getSandbox = lodash.once((): CodeSandbox => { +const createCodeSandbox = (): CodeSandbox => { // 需要被注入到 `sandbox` 中的键值对 const injection = new Map([ // 加固,防止逃逸 @@ -55,8 +58,9 @@ const getSandbox = lodash.once((): CodeSandbox => { return [exported, returned] }, } -}) +} +let staticCodeSandbox: CodeSandbox | undefined /** * 执行 feature (component, plugin, style) 的代码,并尝试获取其导出元数据 * @@ -69,14 +73,15 @@ const getSandbox = lodash.once((): CodeSandbox => { * * 代码默认以非严格模式执行,启用需自行添加 `use strict`。(从本项目中打包的 feature 自带严格模式) * - * 全局对象为脚本管理器提供的 `window`,支持访问 `unsafeWindow`。 + * 代码执行时的全局对象为脚本管理器提供的 `window`。代码中支持访问 `unsafeWindow`。 * * @param code - 被执行的代码 - * @returns 导出的元数据(不检测正确性) + * @returns 导出的元数据(不检测是否为正确的 feature) * @throws {@link LoadFeatureCodeError} * 代码包含语法错误或代码执行时产生了异常 */ export const loadFeatureCode = (code: string): unknown => { - const [exported, returned] = getSandbox().run(code) + staticCodeSandbox || (staticCodeSandbox = createCodeSandbox()) + const [exported, returned] = staticCodeSandbox.run(code) return exported || returned } From 3fd8f6ddb0eca6400d92f12413a162f96a4fc2c0 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 20 Feb 2023 04:05:27 +0800 Subject: [PATCH 05/52] Change interface to type alias --- src/core/external-input/load-feature-code.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/external-input/load-feature-code.ts b/src/core/external-input/load-feature-code.ts index 95ef0d805..0b283d780 100644 --- a/src/core/external-input/load-feature-code.ts +++ b/src/core/external-input/load-feature-code.ts @@ -3,7 +3,7 @@ export class LoadFeatureCodeError extends Error {} /** * feature 代码运行沙箱 */ -interface CodeSandbox { +type CodeSandbox = { /** * 在沙箱中执行代码 * From ec5bcdc908d49508821d9334d8e6e62598a2174f Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Mon, 20 Feb 2023 05:26:39 +0800 Subject: [PATCH 06/52] Fix type errors of IframePopup.vue --- .../style/custom-navbar/iframe/IframePopup.vue | 9 +++++++++ .../lib/components/style/custom-navbar/iframe/iframe.ts | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/style/custom-navbar/iframe/IframePopup.vue b/registry/lib/components/style/custom-navbar/iframe/IframePopup.vue index 099477608..a57a5fdd7 100644 --- a/registry/lib/components/style/custom-navbar/iframe/IframePopup.vue +++ b/registry/lib/components/style/custom-navbar/iframe/IframePopup.vue @@ -3,10 +3,19 @@ diff --git a/registry/lib/components/style/custom-navbar/iframe/iframe.ts b/registry/lib/components/style/custom-navbar/iframe/iframe.ts index 770841e25..2be4cd53e 100644 --- a/registry/lib/components/style/custom-navbar/iframe/iframe.ts +++ b/registry/lib/components/style/custom-navbar/iframe/iframe.ts @@ -1,6 +1,6 @@ import { CustomNavbarItemInit } from '../custom-navbar-item' -interface NavbarIframeConfig { +export interface NavbarIframeConfig { src: string href: string width: number From ce201a0c04e005003b44ba0fb8091069703d139b Mon Sep 17 00:00:00 2001 From: the1812 Date: Mon, 20 Feb 2023 09:04:34 +0800 Subject: [PATCH 07/52] Fix undefined properties (fix #3992) --- .../style/custom-navbar/feeds/tabs/LiveFeeds.vue | 2 +- registry/lib/components/utils/dev-client/Widget.vue | 7 ------- src/core/toast/MiniToast.vue | 3 +-- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/registry/lib/components/style/custom-navbar/feeds/tabs/LiveFeeds.vue b/registry/lib/components/style/custom-navbar/feeds/tabs/LiveFeeds.vue index c0e0608b3..1a23120a7 100644 --- a/registry/lib/components/style/custom-navbar/feeds/tabs/LiveFeeds.vue +++ b/registry/lib/components/style/custom-navbar/feeds/tabs/LiveFeeds.vue @@ -9,7 +9,7 @@
{{ c.title }}
-
{{ c.upName }}
+
{{ c.upName }}
diff --git a/registry/lib/components/utils/dev-client/Widget.vue b/registry/lib/components/utils/dev-client/Widget.vue index b48e90862..20c43785a 100644 --- a/registry/lib/components/utils/dev-client/Widget.vue +++ b/registry/lib/components/utils/dev-client/Widget.vue @@ -34,8 +34,6 @@ export default Vue.extend({ data() { return { client: null, - // sessions: [], - // devRecords: options.devRecords, isConnected: false, } }, @@ -44,12 +42,10 @@ export default Vue.extend({ this.client = devClient this.updateConnectionStatus() devClient.addEventListener(DevClientEvents.ServerChange, this.updateConnectionStatus) - // devClient.addEventListener(DevClientEvents.SessionsUpdate, this.updateSessionsStatus) }, beforeDestroy() { const devClient = this.client as DevClient devClient.removeEventListener(DevClientEvents.ServerChange, this.updateConnectionStatus) - // devClient.removeEventListener(DevClientEvents.SessionsUpdate, this.updateSessionsStatus) }, methods: { async connect() { @@ -61,9 +57,6 @@ export default Vue.extend({ updateConnectionStatus() { this.isConnected = this.client.isConnected }, - updateSessionsStatus() { - this.sessions = [...this.client.sessions] - }, }, }) diff --git a/src/core/toast/MiniToast.vue b/src/core/toast/MiniToast.vue index bddf4075f..7971e47c5 100644 --- a/src/core/toast/MiniToast.vue +++ b/src/core/toast/MiniToast.vue @@ -49,8 +49,7 @@ export default Vue.extend({ async mounted() { await this.$nextTick() const appendTarget = containerMap[this.container] - this.toast = createMiniToast(this.message, this.$refs.content, { - content: this.$refs.toast, + this.toast = createMiniToast(this.$refs.toast, this.$refs.content, { placement: this.placement, showOnCreate: this.show, trigger: 'mouseenter focusin', From 6ad8b3e27bff49fcda3d87bb7245633f3e28d975 Mon Sep 17 00:00:00 2001 From: JLoeve <34429322+LonelySteve@users.noreply.github.com> Date: Mon, 20 Feb 2023 22:40:53 +0800 Subject: [PATCH 08/52] fix: Improve bisector --- src/components/bisector/DialogContent.vue | 2 +- src/components/bisector/api.ts | 6 +++--- src/components/bisector/index.ts | 2 +- src/core/utils/index.ts | 8 -------- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/components/bisector/DialogContent.vue b/src/components/bisector/DialogContent.vue index 9ef26d981..544247986 100644 --- a/src/components/bisector/DialogContent.vue +++ b/src/components/bisector/DialogContent.vue @@ -40,7 +40,7 @@ export default Vue.extend({ diff --git a/registry/lib/components/style/custom-navbar/subscriptions/SubscriptionsList.vue b/registry/lib/components/style/custom-navbar/subscriptions/SubscriptionsList.vue index a24478bbd..c894f3757 100644 --- a/registry/lib/components/style/custom-navbar/subscriptions/SubscriptionsList.vue +++ b/registry/lib/components/style/custom-navbar/subscriptions/SubscriptionsList.vue @@ -46,12 +46,8 @@ import { logError } from '@/core/utils/log' import { DpiImage, VLoading, VEmpty, VIcon, ScrollTrigger } from '@/ui' import { getJsonWithCredentials } from '@/core/ajax' import { SubscriptionTypes } from './subscriptions' +import { SubscriptionItem, SubscriptionStatus, SubscriptionStatusFilter } from './types' -enum SubscriptionStatus { - ToView = 1, - Viewing, - Viewed, -} const getStatusText = (status: SubscriptionStatus) => { switch (status) { case SubscriptionStatus.ToView: @@ -63,10 +59,7 @@ const getStatusText = (status: SubscriptionStatus) => { return '看过' } } -const subscriptionSorter = ( - a: { status: SubscriptionStatus }, - b: { status: SubscriptionStatus }, -) => { +const subscriptionSorter = (a: SubscriptionItem, b: SubscriptionItem) => { let statusA = a.status if (statusA !== SubscriptionStatus.Viewed) { statusA = SubscriptionStatus.Viewed - statusA @@ -86,6 +79,10 @@ export default Vue.extend({ ScrollTrigger, }, props: { + filter: { + type: [Object, null], + default: null, + }, type: { type: String, default: SubscriptionTypes.Bangumi, @@ -99,12 +96,21 @@ export default Vue.extend({ page: 1, } }, + watch: { + filter() { + this.cards = [] + this.loading = true + this.page = 1 + this.nextPage() + }, + }, async created() { this.nextPage() }, methods: { async nextPage() { try { + const filter = this.filter as SubscriptionStatusFilter const json = await getJsonWithCredentials( `https://api.bilibili.com/x/space/bangumi/follow/list?type=${ this.type !== SubscriptionTypes.Bangumi ? '2' : '1' @@ -114,10 +120,10 @@ export default Vue.extend({ logError(`加载订阅信息失败: ${json.message}`) return } - const cards = lodash + const newCards: SubscriptionItem[] = lodash .uniqBy( - (this.cards as any[]).concat( - (lodash.get(json, 'data.list') as any[]).map(item => ({ + (lodash.get(json, 'data.list') as any[]).map( + (item): SubscriptionItem => ({ title: item.title, coverUrl: item.square_cover.replace('http:', 'https:'), latest: item.new_ep.index_show, @@ -127,14 +133,20 @@ export default Vue.extend({ statusText: getStatusText(item.follow_status), playUrl: `https://www.bilibili.com/bangumi/play/ss${item.season_id}`, mediaUrl: `https://www.bilibili.com/bangumi/media/md${item.media_id}`, - })), + }), ), card => card.id, ) + .filter(card => { + if (filter.viewAll) { + return true + } + return card.status === filter.status + }) .sort(subscriptionSorter) this.page++ - this.cards = cards - this.hasMorePage = lodash.get(json, 'data.total', 0) > this.cards.length + this.cards = this.cards.concat(newCards) + this.hasMorePage = newCards.length > 0 } finally { this.loading = false } diff --git a/registry/lib/components/style/custom-navbar/subscriptions/types.ts b/registry/lib/components/style/custom-navbar/subscriptions/types.ts new file mode 100644 index 000000000..1b236bed5 --- /dev/null +++ b/registry/lib/components/style/custom-navbar/subscriptions/types.ts @@ -0,0 +1,20 @@ +export enum SubscriptionStatus { + ToView = 1, + Viewing, + Viewed, +} +export interface SubscriptionStatusFilter { + viewAll: boolean + status: SubscriptionStatus +} +export interface SubscriptionItem { + title: string + coverUrl: string + latest: number + progress: string + id: string + status: SubscriptionStatus + statusText: string + playUrl: string + mediaUrl: string +} diff --git a/src/ui/TabControl.vue b/src/ui/TabControl.vue index e71c39d44..23df0cfc6 100644 --- a/src/ui/TabControl.vue +++ b/src/ui/TabControl.vue @@ -84,18 +84,24 @@ export default Vue.extend({ }, }, data() { + const tabs = this.tabs as TabMappings return { - selectedTab: (this.tabs.find((t: TabMapping) => t.name === this.defaultTab) ?? - this.tabs[0]) as TabMapping, + selectedTabName: + tabs.find((t: TabMapping) => t.name === this.defaultTab)?.name ?? tabs[0].name, } }, + computed: { + selectedTab() { + return this.tabs.find((t: TabMapping) => t.name === this.selectedTabName) + }, + }, mounted() { this.$emit('change', this.selectedTab.activeLink) }, methods: { selectTab(tab: TabMapping) { - if (this.selectedTab !== tab) { - this.selectedTab = tab + if (this.selectedTabName !== tab.name) { + this.selectedTabName = tab.name tab.count = 0 this.$emit('change', this.selectedTab.activeLink) } else if (tab.activeLink) { From e422ca01b67602a8c64e09c62d73c86993904506 Mon Sep 17 00:00:00 2001 From: the1812 Date: Tue, 21 Mar 2023 23:58:41 +0800 Subject: [PATCH 40/52] Add toggle player light (#3587) --- .../keymap/settings/KeymapSettingsRow.vue | 12 +++++++--- .../utils/keymap-toggle-player-light/index.ts | 22 +++++++++++++++++++ src/components/video/player-agent/base.ts | 7 +++++- src/components/video/player-light.ts | 3 ++- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 registry/lib/plugins/utils/keymap-toggle-player-light/index.ts diff --git a/registry/lib/components/utils/keymap/settings/KeymapSettingsRow.vue b/registry/lib/components/utils/keymap/settings/KeymapSettingsRow.vue index 97f9e8309..1a553e678 100644 --- a/registry/lib/components/utils/keymap/settings/KeymapSettingsRow.vue +++ b/registry/lib/components/utils/keymap/settings/KeymapSettingsRow.vue @@ -4,7 +4,7 @@ {{ row.displayName }}
+
{ + addData('keymap.actions', (actions: Record) => { + actions.togglePlayerLight = { + displayName: '开关灯', + run: async () => { + toggleLight() + }, + } + }) + addData('keymap.presets', (presetBase: Record) => { + presetBase.togglePlayerLight = 'shift l' + }) + }, +} diff --git a/src/components/video/player-agent/base.ts b/src/components/video/player-agent/base.ts index 7286e4036..e24264fb4 100644 --- a/src/components/video/player-agent/base.ts +++ b/src/components/video/player-agent/base.ts @@ -70,8 +70,13 @@ export abstract class PlayerAgent { } /** true 开灯,false 关灯 */ - async toggleLight(on: boolean) { + async toggleLight(on?: boolean) { const checkbox = (await this.query.control.settings.lightOff()) as HTMLInputElement + // 无指定参数, 直接 toggle + if (on === undefined) { + checkbox.click() + return + } // 关灯状态 && 要开灯 -> 开灯 checkbox.checked && on && checkbox.click() // 开灯状态 && 要关灯 -> 关灯 diff --git a/src/components/video/player-light.ts b/src/components/video/player-light.ts index f5f07106c..91a164ada 100644 --- a/src/components/video/player-light.ts +++ b/src/components/video/player-light.ts @@ -5,7 +5,7 @@ import { playerAgent } from './player-agent' // let initialized = false -const setLight = (on: boolean) => { +const setLight = (on?: boolean) => { if (!playerUrls.some(url => matchUrlPattern(url))) { return none } @@ -27,3 +27,4 @@ const setLight = (on: boolean) => { export const lightOn = setLight(true) export const lightOff = setLight(false) +export const toggleLight = setLight() From 68d7c30d71792e0d0b765e5b59c0a271bdd9b38b Mon Sep 17 00:00:00 2001 From: Pencil <36183335+pencilqaq@users.noreply.github.com> Date: Fri, 24 Mar 2023 19:58:04 +0800 Subject: [PATCH 41/52] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E7=9B=B4=E6=92=AD?= =?UTF-8?q?=E9=97=B4=E7=AE=80=E5=8C=96=20=E7=A4=BC=E7=89=A9=E6=A0=8F=20?= =?UTF-8?q?=E9=94=99=E4=BD=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/style/simplify/live/live.scss | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/registry/lib/components/style/simplify/live/live.scss b/registry/lib/components/style/simplify/live/live.scss index 16e88d531..25f8636ae 100644 --- a/registry/lib/components/style/simplify/live/live.scss +++ b/registry/lib/components/style/simplify/live/live.scss @@ -214,6 +214,29 @@ $prefix: 'simplifyLiveroom-switch'; } } } + .gift-control-panel { + .more-gift-section{ + position: static !important; + margin: 0 10px 0 0 !important; + height: 48px !important; + } + .z-gift-package{ + margin: auto 0 !important; + position: static !important; + .gift-package{ + margin-top: 2px; + } + } + .right-part{ + padding-top: 0 !important; + } + .right-section > .gift-section{ + height: 42px !important; + } + .battery-pic{ + display: none !important; + } + } } .#{$prefix}-guard { .guard-danmaku::before { From 19c9859b496514fab4ca4f6e29e8075a670cfc9a Mon Sep 17 00:00:00 2001 From: the1812 Date: Sat, 25 Mar 2023 17:55:50 +0800 Subject: [PATCH 42/52] Refactor & format PR codes --- .../components/style/dark-mode/dark-fix.scss | 105 --------------- .../components/style/dark-mode/dark-mode.scss | 1 - .../style/dark-mode/dark-slice-17.scss | 126 +++++++++++++++++- .../components/style/simplify/live/live.scss | 12 +- .../video/player/auto-light/animation.ts | 64 +++++++++ .../video/player/auto-light/index.ts | 98 ++------------ 6 files changed, 208 insertions(+), 198 deletions(-) delete mode 100644 registry/lib/components/style/dark-mode/dark-fix.scss create mode 100644 registry/lib/components/video/player/auto-light/animation.ts diff --git a/registry/lib/components/style/dark-mode/dark-fix.scss b/registry/lib/components/style/dark-mode/dark-fix.scss deleted file mode 100644 index e67faa1b0..000000000 --- a/registry/lib/components/style/dark-mode/dark-fix.scss +++ /dev/null @@ -1,105 +0,0 @@ -[class*="numberListItem_number_list_item"] { - background-color: #555; - border: 1px solid #555; -} - -[class*="review_review_module"] [class*="review_module_content"] [class*="review_review_item"] [class*="review_review_item_fill"] [class*="review_review_header"] [class*="review_review_author"], -[class*="seasonlist_season_list"] [class*="seasonlist_ss_list_wrapper"] [class*="seasonlist_ss_item"] [class*="seasonlist_ss_info"] [class*="seasonlist_ss_title"], -[class*="review_review_module"] [class*="review_module_title"], -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_desc"] i, -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_desc"], -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_title"], -[class*="epitem_ep_item"] a, -[class*="section_ep_section_module"] [class*="section_section_title"], -[class*="RecommendItem_wrap"] [class*="RecommendItem_right_wrap"] [class*="RecommendItem_title"], -[class*="eplist_ep_list_wrapper"] [class*="eplist_list_title"] [class*="eplist_left_wrap"] h4, -[class*="numberListItem_title"] { - color: #eee; -} - -[class*="numberListItem_number_list_item"][class*="numberListItem_select"] { - border: 2px solid #747474; - background-color: #555; -} - -[class*="numberListItem_number_list_item"][class*="numberListItem_select"] [class*="numberListItem_title"] { - color: #00a1d6; - font-weight: 700; -} - -[class*="numberListItem_number_list_item"]:hover { - border: 2px solid #747474; - color: #747474 -} - -[class*="epitem_ep_item"]:hover { - background-color: #555; -} - -[class*="epitem_ep_item"][class*="epitem_cursor"] { - background-color: #555; - color: #00a1d6 -} - -[class*="epitem_cursor"] > a { - color: #00a1d6 -} - -[class*="review_review_module"] [class*="review_module_content"] [class*="review_review_item"] [class*="review_review_item_fill"] [class*="review_review_body"] [class*="review_review_title"], -[class*="review_review_module"] [class*="review_module_content"] [class*="review_review_item"] [class*="review_review_item_fill"] [class*="review_review_body"] [class*="review_review_content"], -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_pub"] [class*="mediainfo_home_link"], -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_pub"] [class*="mediainfo_av_link"], -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_pub"] { - color: #aaa; -} - -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_desc"] i { - font-weight: 700; -} - - -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_desc"] i, -[class*="mediainfo_media_info"] [class*="mediainfo_media_right"] [class*="mediainfo_media_desc_section"] [class*="mediainfo_display_area"] [class*="mediainfo_ellipsis"] { - background: none; - color: #eee; - font-weight: 700; -} - -[class*="operation_split_line"], -[class*="mediainfo_media_info"] { - border-top: 1px solid #444; -} - -[class*="review_review_module"] { - border-bottom: 1px solid #444 -} - -.bb-comment .reply-notice .notice-item { - background-color: #444 !important; -} - -.bb-comment .comment-header .tabs-order li.on { - color: #eee !important; -} - -.bb-comment .comment-header .tabs-order li { - color: #888 !important; -} - -[id*="weslie-media-info-review"], -[class^="eplist_ep_list_wrapper"], -[id^="list_module"], -[class*="section_ep_section_module"], -[class*="review_review_item_fill"] { - background-color: #444 !important; -} - -[class*="DanmukuBox_wrap"] { - background: none; -} - -[class*="seasonlist_season_list"] [class*="seasonlist_ss_list_wrapper"] [class*="seasonlist_expand_more"] { - background-color: #444; - color: #eee; -} - diff --git a/registry/lib/components/style/dark-mode/dark-mode.scss b/registry/lib/components/style/dark-mode/dark-mode.scss index cc3847e97..9558efb73 100644 --- a/registry/lib/components/style/dark-mode/dark-mode.scss +++ b/registry/lib/components/style/dark-mode/dark-mode.scss @@ -17,4 +17,3 @@ @import "./dark-slice-17.scss"; @import "./dark-navbar.scss"; @import "./dark-variables.scss"; -@import "./dark-fix.scss"; diff --git a/registry/lib/components/style/dark-mode/dark-slice-17.scss b/registry/lib/components/style/dark-mode/dark-slice-17.scss index 760c76685..be54c5e96 100644 --- a/registry/lib/components/style/dark-mode/dark-slice-17.scss +++ b/registry/lib/components/style/dark-mode/dark-slice-17.scss @@ -888,9 +888,133 @@ .startlive-icon { @include to-theme('blue'); } -.right-area .tip-wrap .icon path[fill="#00AEEC"] { +.right-area .tip-wrap .icon path[fill='#00AEEC'] { @include theme-fill(); } .bpx-player-pbp-videoshot rect[clip-path] { @include theme-fill(); } + +[class*='numberListItem_number_list_item'] { + @include background-color('5'); + @include border-color(); + &:hover { + @include theme-border-color(); + } + &[class*='numberListItem_select'] { + @include theme-border-color(); + [class*='numberListItem_title'] { + @include theme-color(); + } + } +} + +[class*='review_review_module'] { + @include border-color('4'); + + [class*='review_review_item_fill'] { + @include background-color('4'); + } + + [class*='review_module_title'], + [class*='review_review_title'] { + @include color('e'); + } + + [class*='review_review_author'] { + @include color('e'); + &[class*='review_is-vip'] { + @include vip-color(); + } + } + [class*='review_review_content'] { + @include color('a'); + } +} + +[class*='epitem_ep_item'] { + &:hover { + @include background-color('5'); + } + + a { + @include color('e'); + &:hover { + @include theme-color(); + } + } + + &[class*='epitem_cursor'] { + @include background-color('5'); + path { + @include theme-fill(); + } + } +} + +[class*='seasonlist_season_list'] { + [class*='seasonlist_ss_title'] { + @include color('e'); + } + [class*='seasonlist_expand_more'] { + @include background-color('4'); + @include color('e'); + } +} + +[class*='mediainfo_media_info'] { + @include border-color('4'); + + [class*='mediainfo_media_desc'] { + &, + & i { + @include color('e'); + } + } + [class*='mediainfo_media_title'] { + @include color('e'); + } + [class*='mediainfo_av_link'], + [class*='mediainfo_home_link'], + [class*='mediainfo_media_pub'] { + @include color('a'); + } + + [class*='mediainfo_ellipsis'], + [class*='mediainfo_media_desc'] i { + @include background(); + @include theme-color(); + } +} + +[class*='section_ep_section_module'] { + @include background-color('4'); + [class*='section_section_title'] { + @include color('e'); + } +} + +[class*='RecommendItem_wrap'] { + [class*='RecommendItem_title'] { + @include color('e'); + } +} + +[class*='eplist_ep_list_wrapper'] { + @include background-color('4'); + [class*='eplist_list_title'] [class*='eplist_left_wrap'] h4 { + @include color('e'); + } + [class*='numberListItem_title'] { + @include color('e'); + } +} +[class*='operation_split_line'] { + @include border-color('4'); +} +[class*='mediainfo_btn_rating'] { + @include background-color(); +} +[class*='DanmukuBox_wrap'] { + @include background(); +} diff --git a/registry/lib/components/style/simplify/live/live.scss b/registry/lib/components/style/simplify/live/live.scss index 25f8636ae..16e327050 100644 --- a/registry/lib/components/style/simplify/live/live.scss +++ b/registry/lib/components/style/simplify/live/live.scss @@ -215,25 +215,25 @@ $prefix: 'simplifyLiveroom-switch'; } } .gift-control-panel { - .more-gift-section{ + .more-gift-section { position: static !important; margin: 0 10px 0 0 !important; height: 48px !important; } - .z-gift-package{ + .z-gift-package { margin: auto 0 !important; position: static !important; - .gift-package{ + .gift-package { margin-top: 2px; } } - .right-part{ + .right-part { padding-top: 0 !important; } - .right-section > .gift-section{ + .right-section > .gift-section { height: 42px !important; } - .battery-pic{ + .battery-pic { display: none !important; } } diff --git a/registry/lib/components/video/player/auto-light/animation.ts b/registry/lib/components/video/player/auto-light/animation.ts new file mode 100644 index 000000000..12df49ff1 --- /dev/null +++ b/registry/lib/components/video/player/auto-light/animation.ts @@ -0,0 +1,64 @@ +// author: https://github.com/z503722728 + +const CreateAnim = (): void => { + const biliMainHeader = document.getElementById('biliMainHeader') + if (biliMainHeader == null) { + return + } + const mstars1 = document.createElement('div') + mstars1.id = 'mstars1' + const mstars2 = document.createElement('div') + mstars2.id = 'mstars2' + biliMainHeader.appendChild(mstars1) + biliMainHeader.appendChild(mstars2) + + // 添加一段css 样式到document最后 + const style = document.createElement('style') + // generate random stars + function generate(numCtrl) { + let star = '' + const max = window.innerWidth * window.innerHeight + for (let i = 0; i < max / numCtrl; i++) { + const x = Math.floor(Math.random() * window.innerWidth * 1.5) + const y = Math.floor(Math.random() * (window.innerHeight + 2000)) + star += `${x}px ${y}px #FFF,` + } + const x = Math.floor(Math.random() * window.innerWidth * 1.5) + const y = Math.floor(Math.random() * (window.innerHeight + 2000)) + star += `${x}px ${y}px #FFF;` + return star + } + const starNumCtl = 400 + const stars1Shadow = generate(starNumCtl) + const stars2Shadow = generate(starNumCtl * 2) + const stars3Shadow = generate(starNumCtl * 4) + const stars4Shadow = generate(starNumCtl * 8) + style.innerHTML = ` + #mstars1{z-index: 1009;position: fixed;left:0px; width:1px;height:1px;background:transparent;box-shadow:${stars1Shadow};animation:animStar 50s linear infinite} + #mstars1:after{content:' ';position:fixed;left:0px;top:0px;width:1px;height:1px;background:transparent;box-shadow:${stars2Shadow}} + #mstars2{z-index: 1009;position: fixed;left:0px;width:2px;height:2px;background:transparent;box-shadow:${stars3Shadow};animation:animStar 100s linear infinite} + #mstars2:after{content:' ';position:fixed;left:0px;top:0px;width:2px;height:2px;background:transparent;box-shadow:${stars4Shadow}} + @keyframes animStar{from{transform:translateY(-200px)}to{transform:translateY(-2200px)}} + ` + document.body.appendChild(style) +} + +export const StarAnim = (on: boolean) => { + // 查找id mstars1 的div + let mstars1 = document.getElementById('mstars1') + let mstars2 = document.getElementById('mstars2') + // 如果没有找到id biliMainHeader 的div创建2个id为 mstars1 mstars2 的div + if (on) { + if (mstars1 == null) { + CreateAnim() + mstars1 = document.getElementById('mstars1') + mstars2 = document.getElementById('mstars2') + } + // 设置mstars1 mstars2 visible 为true + mstars1.style.visibility = 'visible' + mstars2.style.visibility = 'visible' + } else if (mstars1 != null) { + mstars1.style.visibility = 'hidden' + mstars2.style.visibility = 'hidden' + } +} diff --git a/registry/lib/components/video/player/auto-light/index.ts b/registry/lib/components/video/player/auto-light/index.ts index 068caee90..1333fedd5 100644 --- a/registry/lib/components/video/player/auto-light/index.ts +++ b/registry/lib/components/video/player/auto-light/index.ts @@ -2,100 +2,28 @@ import { playerAgent } from '@/components/video/player-agent' import { lightOn, lightOff } from '@/components/video/player-light' import { videoChange } from '@/core/observer' import { allVideoUrls } from '@/core/utils/urls' -import { newSwitchComponentWrapper, defineSwitchMetadata } from '@/components/switch-options' -import { getComponentSettings } from '@/core/settings' +import type { PlayerAgent } from '@/components/video/player-agent/base' +import { StarAnim } from './animation' +import { defineComponentMetadata } from '@/components/define' -let playerAgentInstance +let playerAgentInstance: PlayerAgent -const CreateAnim = (): void => { - const biliMainHeader = document.getElementById('biliMainHeader') - if (biliMainHeader == null) { - return - } - const mstars1 = document.createElement('div') - mstars1.id = 'mstars1' - const mstars2 = document.createElement('div') - mstars2.id = 'mstars2' - biliMainHeader.appendChild(mstars1) - biliMainHeader.appendChild(mstars2) - - // 添加一段css 样式到document最后 - const style = document.createElement('style') - // generate random stars - function generate(numCtrl) { - let star = '' - const max = window.innerWidth * window.innerHeight - for (let i = 0; i < max / numCtrl; i++) { - const x = Math.floor(Math.random() * window.innerWidth * 1.5) - const y = Math.floor(Math.random() * (window.innerHeight + 2000)) - star += `${x}px ${y}px #FFF,` - } - const x = Math.floor(Math.random() * window.innerWidth * 1.5) - const y = Math.floor(Math.random() * (window.innerHeight + 2000)) - star += `${x}px ${y}px #FFF;` - return star - } - const starNumCtl = 400 - const stars1Shadow = generate(starNumCtl) - const stars2Shadow = generate(starNumCtl * 2) - const stars3Shadow = generate(starNumCtl * 4) - const stars4Shadow = generate(starNumCtl * 8) - style.innerHTML = ` - #mstars1{z-index: 1009;position: fixed;left:0px; width:1px;height:1px;background:transparent;box-shadow:${stars1Shadow};animation:animStar 50s linear infinite} - #mstars1:after{content:' ';position:fixed;left:0px;top:0px;width:1px;height:1px;background:transparent;box-shadow:${stars2Shadow}} - #mstars2{z-index: 1009;position: fixed;left:0px;width:2px;height:2px;background:transparent;box-shadow:${stars3Shadow};animation:animStar 100s linear infinite} - #mstars2:after{content:' ';position:fixed;left:0px;top:0px;width:2px;height:2px;background:transparent;box-shadow:${stars4Shadow}} - @keyframes animStar{from{transform:translateY(-200px)}to{transform:translateY(-2200px)}} - ` - document.body.appendChild(style) -} - -const StarAnim = (on: boolean) => { - // 查找id mstars1 的div - let mstars1 = document.getElementById('mstars1') - let mstars2 = document.getElementById('mstars2') - // 如果没有找到id biliMainHeader 的div创建2个id为 mstars1 mstars2 的div - if (on) { - if (mstars1 == null) { - CreateAnim() - mstars1 = document.getElementById('mstars1') - mstars2 = document.getElementById('mstars2') - } - // 设置mstars1 mstars2 visible 为true - mstars1.style.visibility = 'visible' - mstars2.style.visibility = 'visible' - } else if (mstars1 != null) { - mstars1.style.visibility = 'hidden' - mstars2.style.visibility = 'hidden' - } -} - -const switchMetadata = defineSwitchMetadata({ - name: 'simplifyOptions', - dimAt: 'checked', - switchProps: { - checkedIcon: 'mdi-eye-off-outline', - notCheckedIcon: 'mdi-eye-outline', - }, - switches: { - anim: { - defaultValue: false, - displayName: '隐藏星光动画', - }, - }, -}) - -export const component = newSwitchComponentWrapper(switchMetadata)({ +export const component = defineComponentMetadata({ name: 'playerAutoLight', displayName: '播放时自动关灯', urlInclude: allVideoUrls, tags: [componentsTags.video], + options: { + starAnimation: { + defaultValue: true, + displayName: '启用星光动画', + }, + }, description: { 'zh-CN': '在视频播放时自动关灯, 暂停或结束时再自动打开.', }, - entry: async ({ metadata }) => { + entry: async ({ settings }) => { const { isEmbeddedPlayer } = await import('@/core/utils') - const { options } = getComponentSettings(metadata.name) if (isEmbeddedPlayer()) { return @@ -108,7 +36,7 @@ export const component = newSwitchComponentWrapper(switchMetadata)({ const makeLightOff = () => { lightOff() - if (!options['switch-anim']) { + if (!settings.options.starAnimation) { StarAnim(true) } } From 7f6af7ff6a6a7bbd4f071adc748aac8e31b798fb Mon Sep 17 00:00:00 2001 From: the1812 Date: Sat, 25 Mar 2023 18:22:16 +0800 Subject: [PATCH 43/52] Update docs --- CONTRIBUTING.md | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67dd0d6a9..b6e92abfa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,10 @@ # 代码贡献指南 +Bilibili Evolved 是一个基于 Web 前端技术构建的油猴脚本, 贡献代码前应具备的相关能力有: +- 了解最基础的油猴脚本的开发流程, 包括理解 [UserScript Header 和 GM API](https://www.tampermonkey.net/documentation.php?locale=en). +- 熟悉 Web 前端技术, 编写逻辑时使用 [TypeScript](https://www.typescriptlang.org/), 编写样式时使用 [Scss](https://sass-lang.com/), 创建 UI 时使用 [Vue 2](https://v2.cn.vuejs.org/). +- 新增的代码能够通过 [ESLint](https://eslint.org/) 和 [TypeScript](https://www.typescriptlang.org/) 检查. + ## 搭建开发环境 - 需要安装 [Node.js](https://nodejs.org/en/download/) (>= 14.0), [Visual Studio Code](https://code.visualstudio.com/) 和 [pnpm](https://pnpm.io/installation). @@ -13,6 +18,10 @@ cd registry pnpm install ``` +- [配置 VS Code 插件](https://code.visualstudio.com/docs/editor/extension-marketplace): + - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), 用于格式化 TypeScript 和 Vue 文件. + - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode), 用于格式化 Scss 和其他文件. + ### 本体 需要说明的是, 脚本本体和功能是分开的两个项目. 本体的代码在 `src/` 下, 开发时产生 `dist/bilibili-evolved.dev.user.js` 文件. 功能的代码位于 `registry/` 下, 开发时在 `registry/dist/` 下产生文件. > 如果不使用 Visual Studio Code, 则需要根据 `.vscode/tasks.json` 中各个任务定义的命令手动在终端执行. (npm scripts 仅用于 CI) @@ -20,10 +29,11 @@ pnpm install 配置本地调试环境: **如果使用的是基于 Chromium 的浏览器** -1. Chrome 插件管理 `chrome://extensions/` > Tampermonkey > 详细信息 -2. 打开 `允许访问文件网址` -3. 新建脚本 -4. 粘贴内容: +1. VS Code 中运行 `启动开发服务 dev-server` 任务, 会在项目的 `dist/` 文件夹下生成一个开发用的脚本 `dist/bilibili-evolved.dev.user.js`. +2. Chrome 插件管理 `chrome://extensions/` > Tampermonkey > 详细信息 +3. 打开 `允许访问文件网址` +4. 新建脚本 +5. 粘贴内容: ```js // ==UserScript== // @name Bilibili Evolved (Local) @@ -63,24 +73,20 @@ pnpm install // @connect localhost // @connect * // @require https://raw.githubusercontent.com/lodash/lodash/4.17.15/dist/lodash.min.js +// @require file://{{ bilibili-evolved.dev.user.js的绝对路径 }} // @icon https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/logo-small.png // @icon64 https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/logo.png -// @require file://{{ bilibili-evolved.dev.user.js的绝对路径 }} // ==/UserScript== ``` -6. 在那些 `@require` 下面再添加一行 `@require file://{{ bilibili-evolved.dev.user.js的绝对路径 }}` -> Windows 例子: `@require file://C:/xxx/Bilibili-Evolved/bilibili-evolved.dev.user.js` -> macOS 例子: `@require file:///Users/xxx/Documents/Bilibili-Evolved/bilibili-evolved.dev.user.js` +6. 将里面的 `{{ bilibili-evolved.dev.user.js的绝对路径 }}` 替换为第一步生成的文件的真实路径. +> Windows 例子: `@require file://C:/xxx/Bilibili-Evolved/dist/bilibili-evolved.dev.user.js` + +> macOS 例子: `@require file:///Users/xxx/Documents/Bilibili-Evolved/dist/bilibili-evolved.dev.user.js` > 上面那些其他的 @require 跟 `src/client/common.meta.json` 里的保持一致就行, 偶尔这些依赖项会变动导致这个本地调试脚本失效, 到时候照着改一下就行. -> 必须放到// ==/UserScript== 之前 不然会加载不到该脚本 - -> 该bilibili-evolved.dev.user.js脚本 需要在vs code->终端>运行任务..->本地:编辑开发版本生成 目录为Bilibili-Evolved/dist/bilibili-evolved.dev.user.js -7. 保存脚本, 运行 `启动开发服务 dev-server` 任务 -8. 进入 b 站, 安装 `DevClient` 组件, 功能中显示已连接时就是成功了 - +7. 进入 b 站, 安装 `DevClient` 组件, 功能中显示已连接时就是成功了 **如果使用 Firefox 或 Safari** 1. 运行 `启动开发服务 dev-server` 任务时, 假设得到的本体链接为 `http://localhost:23333/dist/bilibili-evolved.dev.user.js` @@ -143,6 +149,7 @@ pnpm install ## 可用资源 本体提供了大量 API 供组件 / 插件使用. + ### 全局 全局变量, 无需 `import` 就可以直接使用. (Tampermonkey API 这里不再列出了, 可根据代码提示使用) @@ -235,7 +242,11 @@ pnpm install - `ui/AsyncButton.vue`: `click` 事件为异步函数时, 执行期间自动使 `Button` 禁用, 其他和 `Button` 相同. ## 代码风格检查 -项目中含有 ESLint, 不通过 ESLint 是无法进行 Pull Request 的. 配置基于 `airbnb-base`, `typescript-eslint/recommended`, `vue/recommended` 修改而来, 几个比较特殊的规则如下: +项目中含有 ESLint, 不通过 ESLint 是无法进行 Pull Request 的. + +你可以使用 [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 插件实时检查当前代码, 也可以运行 `生产:代码检查 prod:lint` 或 `生产:代码修复 prod:lint-fix` 来使用 ESLint 的命令行进行检查. + +配置基于 `airbnb-base`, `typescript-eslint/recommended`, `vue/recommended` 修改而来, 几个比较特殊的规则如下: ### 强制性 - 除了 Vue 单文件组件, 禁止使用 `export default`, 所有导出必须命名. @@ -248,12 +259,11 @@ pnpm install - 不需要使用 `this` 特性的函数, 均使用箭头函数. ## 提交 commit -仅提交源代码上的修改即可, 不建议把 dist 文件夹里的产物也提交, 否则容易在 PR 时产生冲突. +仅提交源代码上的修改即可, 不要把 dist 文件夹里的产物也提交, 产物会在发布新版本时在对应的生产分支上构建. commit message 只需写明改动点, 中英文随意, 也不强求类似 [commit-lint](https://github.com/conventional-changelog/commitlint) 的格式. ## 发起 PR (合并请求) 将你的分支往主仓库的 `preview-features` (新增功能) 或 `preview-fixes` (功能修复) 分支合并就行. -## 自行保留 -你可以选择不将功能代码合并到主仓库, 因此也没有 ESLint 的限制. PR 时仅添加指向你的仓库中的组件信息即可, 具体来说, 是在 `registry/lib/docs/third-party.ts` 中, 往对应数组中添加你的功能的相关信息, 当然别忘了把 `owner` 设为你的 GitHub 用户名. +或者, 也可以选择不将功能代码合并到主仓库, 因此也没有 ESLint 的限制. PR 时仅添加指向你的仓库中的组件信息即可, 具体来说, 是在 `registry/lib/docs/third-party.ts` 中, 往对应数组中添加你的功能的相关信息, 当然别忘了把 `owner` 设为你的 GitHub 用户名. From e7c1fc22a21d3e35cb09e4d33ba1b33ca18a3a43 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 00:04:32 +0800 Subject: [PATCH 44/52] Update changelog --- CHANGELOG.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d0ea017c..cc3a02c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,63 @@ # 更新日志 +## v2.7.0-preview +`2023-03-26` + +包含 v2.7.0 的所有更新内容. + +- 新增功能 `组件二等分`, 在出现问题时可帮助定位是哪个组件导致的问题. (#3829, PR #3965 by [JLoeve](https://github.com/LonelySteve)) +- 优化了 `loadFeatureCode` 的代码. (PR #4013 by [timongh](https://github.com/timongh)) +- 搜索栏在搜索 ID 时的优化, 新增功能可以通过安装对应的插件来使用: (#677) + - 搜索 av / BV 号时, 支持显示视频标题 + - 支持搜索专栏 cv 号 / 文集 rl 号 + - 支持搜索音频 au 号 / 播放列表 am 号 + - 支持搜索番剧 ss / ep 号, 或番剧详情 md 号 +- `自定义顶栏` 的收藏和稍后再看支持显示数量. (#4069) +- 优化了 `网址参数清理` 的逻辑, 通过 Hook History API 来减少出现重复的历史记录. (#4039) +- 新增功能 `隐藏热搜`. (#3744) +> 隐藏搜索栏和搜索页面中的 `bilibili 热搜`. +- 新增功能 `动态图片限高`. (#4029) +> 在动态里查看图片时 (非全屏), 限制高度不超过一屏, 超过则可滚动, 避免长图看完后动态被顶到很上面. +- 新增功能 `隐藏视频分享`. (#3663) +> 隐藏视频和番剧播放器下方的分享按钮. +- `自定义顶栏` 的订阅支持过滤 在看 / 看过 / 想看. (#3217) +- 新增插件 `快捷键扩展 - 开关灯`. (#3587) +> 在快捷键的动作列表里添加一个 "开关灯". + +## v2.7.0 +`2023-03-26` + +增加了 GitHub Projects 看板: https://github.com/users/the1812/projects/1/views/3, 上面会列出当前和未来计划的功能, 可供参考. + +✨新增 +- 快捷键扩展的几个插件自带了 YouTube / PotPlayer 等预设的默认按键. (#3971) +- `简化直播间` 在开启隐藏付费礼物时, 将直接隐藏左下角的打榜入口 (以前是领银瓜子所以没算进付费礼物). (#4067) +- `专栏文字选择` 更名为 `专栏复制优化`, 现在专栏的文字默认就可以直接选择, 本功能可以用于去除复制后带上的多余文本. (#4065) +- 删除功能 `直播录像下载`, 现在已经没有直播录像的页面了. (#4061) +- 在检测到[解除番剧区域限制](https://greasyfork.org/zh-CN/scripts/25718-%E8%A7%A3%E9%99%A4b%E7%AB%99%E5%8C%BA%E5%9F%9F%E9%99%90%E5%88%B6)的脚本在运行时, 本脚本将停止运行以避免兼容性问题. (#2704) +- `选集区域优化` 在多个分组时支持仅展开当前分组. (#3899) +- `播放时自动关灯` 支持星光动画. (PR #4077 by [z503722728](https://github.com/z503722728)) + +🐛修复 +- 修复 `直播信息扩充` 失效的问题. (#4034, PR #4043 by [deepdarkssj](https://github.com/deepdarkssj)) +- 修复 `简化直播间` 在开启隐藏付费礼物时, 右下布局错乱. (PR #4089 by [Pencil](https://github.com/pencilqaq)) +- 修复动态相关功能对新版专栏卡片不生效. (#3994) +- 修复搜索界面的广告链接仍然可点击. (#3969) +- 修复 `图片批量导出` 在动态失效了. (#4038) +- 修复 `选集区域优化` 仅开启 `展开选集标题` 时视频标题无法显示完全. (#3909) +- 修复 `查看封面` 在复制链接后没有显示成功图标. (#4002) +- 修复番剧页面的部分夜间模式. (PR #4077 by [z503722728](https://github.com/z503722728)) + +☕开发者相关 +- 修复 `IframePopup.vue` 的类型定义. (PR #4014 by [timongh](https://github.com/timongh)) +- 修复 `UserItem.vue` 初始化 Toast 的逻辑问题. (PR #4056 by [timongh](https://github.com/timongh)) +- 优化了 `switch-options.ts` 的注释. (PR #4021 by [timongh](https://github.com/timongh)) +- 清理了项目中 Vue 文件里对未定义字段的引用. (#3992) +- 导出了 Dialog API (`@/core/dialog`), 允许其他组件使用. +- 调整了 CONTRIBUTING 中的本地开发流程描述. (PR #4077 by [z503722728](https://github.com/z503722728)) + ## v2.6.3-preview -`2023-02-09` +`2023-02-20` 包含 v2.6.3 的所有更新内容. From 7ee1b85b66947092529d59de26bef5833730c736 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 14:37:50 +0800 Subject: [PATCH 45/52] Fix missing class filter --- registry/lib/components/style/hide/trending-search/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/registry/lib/components/style/hide/trending-search/index.ts b/registry/lib/components/style/hide/trending-search/index.ts index bf5ef751d..b6bbf495f 100644 --- a/registry/lib/components/style/hide/trending-search/index.ts +++ b/registry/lib/components/style/hide/trending-search/index.ts @@ -14,7 +14,11 @@ export const component = defineComponentMetadata({ entry: async () => { allMutations(records => { records.forEach(record => { - if (record.target instanceof HTMLInputElement && record.target.placeholder !== '搜索') { + if ( + record.target instanceof HTMLInputElement && + record.target.classList.contains('nav-search-input') && + record.target.placeholder !== '搜索' + ) { record.target.placeholder = '搜索' } }) From 25c826ebc1c2e465a08e058fc4748e6db5fac4aa Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 14:48:43 +0800 Subject: [PATCH 46/52] Fix option condition --- registry/lib/components/video/player/auto-light/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/lib/components/video/player/auto-light/index.ts b/registry/lib/components/video/player/auto-light/index.ts index 1333fedd5..6eda24621 100644 --- a/registry/lib/components/video/player/auto-light/index.ts +++ b/registry/lib/components/video/player/auto-light/index.ts @@ -36,7 +36,7 @@ export const component = defineComponentMetadata({ const makeLightOff = () => { lightOff() - if (!settings.options.starAnimation) { + if (settings.options.starAnimation) { StarAnim(true) } } From 84f16a0892c1b652639748825ed84e52ce0bc2c6 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 14:48:43 +0800 Subject: [PATCH 47/52] Fix option condition --- registry/lib/components/video/player/auto-light/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/lib/components/video/player/auto-light/index.ts b/registry/lib/components/video/player/auto-light/index.ts index 1333fedd5..6eda24621 100644 --- a/registry/lib/components/video/player/auto-light/index.ts +++ b/registry/lib/components/video/player/auto-light/index.ts @@ -36,7 +36,7 @@ export const component = defineComponentMetadata({ const makeLightOff = () => { lightOff() - if (!settings.options.starAnimation) { + if (settings.options.starAnimation) { StarAnim(true) } } From 3fa83c2d1843241fe5bc209ac2fc32fb11c82e9d Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 14:52:39 +0800 Subject: [PATCH 48/52] Update changelog --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc3a02c00..dd2009f90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,6 @@ - 优化了 `网址参数清理` 的逻辑, 通过 Hook History API 来减少出现重复的历史记录. (#4039) - 新增功能 `隐藏热搜`. (#3744) > 隐藏搜索栏和搜索页面中的 `bilibili 热搜`. -- 新增功能 `动态图片限高`. (#4029) -> 在动态里查看图片时 (非全屏), 限制高度不超过一屏, 超过则可滚动, 避免长图看完后动态被顶到很上面. - 新增功能 `隐藏视频分享`. (#3663) > 隐藏视频和番剧播放器下方的分享按钮. - `自定义顶栏` 的订阅支持过滤 在看 / 看过 / 想看. (#3217) From 460b1e6c72e23aa2c9a269294054776f85a6608f Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 14:53:08 +0800 Subject: [PATCH 49/52] Update version number --- src/client/common.meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/common.meta.json b/src/client/common.meta.json index 55ee4f64b..193cae80f 100644 --- a/src/client/common.meta.json +++ b/src/client/common.meta.json @@ -1,5 +1,5 @@ { - "version": "2.6.3", + "version": "2.7.0", "author": "Grant Howard, Coulomb-G", "copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)", "license": "MIT", From 6384ca07bd751677393aa353c55ba3d2204466ec Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 15:00:45 +0800 Subject: [PATCH 50/52] Update donate history --- doc/donate.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/donate.md b/doc/donate.md index daae9e92c..f121fe5c0 100644 --- a/doc/donate.md +++ b/doc/donate.md @@ -28,6 +28,16 @@ https://afdian.net/@the1812?tab=sponsor | 时间 | 用户名 | 单号后4位 | 金额 | | ------------------- | ---------------- | --------- | ------- | +| 2023.03.20 21:41:05 | 匿名 | 2237 | ¥6.66 | +| 2023.03.19 22:06:03 | *碧 | 3670 | ¥20.00 | +| 2023.03.15 11:36:31 | k*n | 6491 | ¥1.00 | +| 2023.03.14 00:29:54 | *曰 | 6448 | ¥10.00 | +| 2023.03.14 00:28:35 | *曰 | 8124 | ¥10.00 | +| 2023.03.04 11:47:53 | 匿名 | 0764 | ¥5.00 | +| 2023.02.28 20:56:51 | *肠 | 2857 | ¥10.00 | +| 2023.02.26 19:52:19 | 无*n | 0780 | ¥1.00 | +| 2023.02.20 23:40:27 | 匿名 | 5551 | ¥5.00 | +| 2023.02.20 21:15:04 | 匿名 | 6088 | ¥5.00 | | 2023.02.18 22:49:21 | \*😕\* | 9195 | ¥5.00 | | 2023.02.14 20:40:45 | 匿名 | 9914 | ¥5.00 | | 2023.02.13 12:33:00 | A*l | 2182 | ¥66.00 | From ea23345a106025f4347adeebc42b8260924065e4 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 15:02:14 +0800 Subject: [PATCH 51/52] Update docs --- doc/features/features.json | 12 ++---------- doc/features/features.md | 15 ++++----------- doc/features/pack/pack.json | 19 +++++-------------- doc/features/pack/pack.md | 8 ++------ 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/doc/features/features.json b/doc/features/features.json index ae1882a4d..6a3363199 100644 --- a/doc/features/features.json +++ b/doc/features/features.json @@ -95,14 +95,6 @@ "fullRelativePath": "../../registry/dist/components/live/danmaku-sendbar.js", "fullAbsolutePath": "registry/dist/components/live/danmaku-sendbar.js" }, - { - "type": "component", - "name": "downloadLiveRecords", - "displayName": "直播录像下载", - "description": "在直播录像页面 `live.bilibili.com/record/` 中添加下载支持.", - "fullRelativePath": "../../registry/dist/components/live/download-records.js", - "fullAbsolutePath": "registry/dist/components/live/download-records.js" - }, { "type": "component", "name": "liveGiftBox", @@ -402,8 +394,8 @@ { "type": "component", "name": "columnUnlock", - "displayName": "专栏文字选择", - "description": "使专栏的文字可以选择.", + "displayName": "专栏复制优化", + "description": "(原名: 专栏文字选择, 现在专栏已经不限制选中文字了)\r\n\r\n避免专栏的文字复制后在最后带上出处信息, 更贴近原生的复制行为.\r\n", "fullRelativePath": "../../registry/dist/components/utils/column-unlock.js", "fullAbsolutePath": "registry/dist/components/utils/column-unlock.js" }, diff --git a/doc/features/features.md b/doc/features/features.md index 847023711..1a49bc053 100644 --- a/doc/features/features.md +++ b/doc/features/features.md @@ -116,15 +116,6 @@ 在直播的网页全屏和全屏模式状态下, 在底部显示弹幕栏. -### [直播录像下载](../../registry/dist/components/live/download-records.js) -`downloadLiveRecords` - -**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/live/download-records.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/live/download-records.js) - -**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/live/download-records.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/live/download-records.js) - -在直播录像页面 `live.bilibili.com/record/` 中添加下载支持. - ### [直播全屏包裹](../../registry/dist/components/live/gift-box.js) `liveGiftBox` @@ -487,14 +478,16 @@ by [@snowraincloud](https://github.com/snowraincloud) 在功能面板中提供一些可以每日进行的操作. -### [专栏文字选择](../../registry/dist/components/utils/column-unlock.js) +### [专栏复制优化](../../registry/dist/components/utils/column-unlock.js) `columnUnlock` **jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/utils/column-unlock.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/utils/column-unlock.js) **GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/utils/column-unlock.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/utils/column-unlock.js) -使专栏的文字可以选择. +(原名: 专栏文字选择, 现在专栏已经不限制选中文字了) + +避免专栏的文字复制后在最后带上出处信息, 更贴近原生的复制行为. ### [复制评论链接](../../registry/dist/components/utils/comments/copy-link.js) `copyCommentsLink` diff --git a/doc/features/pack/pack.json b/doc/features/pack/pack.json index 18d61fb88..1883bc0bf 100644 --- a/doc/features/pack/pack.json +++ b/doc/features/pack/pack.json @@ -111,13 +111,12 @@ { "name": "downloader", "displayName": "下载器", - "description": "支持下载各种内容.\n\n包含以下功能:\n下载视频, 下载字幕, 下载弹幕, 下载音频, 直播录像下载", + "description": "支持下载各种内容.\n\n包含以下功能:\n下载视频, 下载字幕, 下载弹幕, 下载音频", "components": [ "downloadVideo", "downloadSubtitle", "downloadDanmaku", - "downloadAudio", - "downloadLiveRecords" + "downloadAudio" ], "items": [ { @@ -151,14 +150,6 @@ "description": "开启音频下载支持, 音频页面中可以在功能面板中下载当前音频.\n\n> 需要进入音频的详细信息页面才能下载, 在其他页面中此按钮将不可点击.", "fullRelativePath": "../../registry/dist/components/utils/download-audio.js", "fullAbsolutePath": "registry/dist/components/utils/download-audio.js" - }, - { - "type": "component", - "name": "downloadLiveRecords", - "displayName": "直播录像下载", - "description": "在直播录像页面 `live.bilibili.com/record/` 中添加下载支持.", - "fullRelativePath": "../../registry/dist/components/live/download-records.js", - "fullAbsolutePath": "registry/dist/components/live/download-records.js" } ], "type": "pack" @@ -166,7 +157,7 @@ { "name": "starter", "displayName": "常用功能包", - "description": "提供一些常用功能.\n\n包含以下功能:\n使用细滚动条, 自定义顶栏, 删除广告, 专栏文字选择, 网址参数清理, 快捷键扩展, 查看封面, BV 号转换, 删除直播水印, 直播弹幕发送栏, 直播全屏包裹, 展开动态内容, 动态反折叠, 快速收起评论, 禁止跳转动态详情, 展开视频简介, 设置面板 - \"最近使用\" 类别", + "description": "提供一些常用功能.\n\n包含以下功能:\n使用细滚动条, 自定义顶栏, 删除广告, 专栏复制优化, 网址参数清理, 快捷键扩展, 查看封面, BV 号转换, 删除直播水印, 直播弹幕发送栏, 直播全屏包裹, 展开动态内容, 动态反折叠, 快速收起评论, 禁止跳转动态详情, 展开视频简介, 设置面板 - \"最近使用\" 类别", "components": [ "elegantScrollbar", "customNavbar", @@ -216,8 +207,8 @@ { "type": "component", "name": "columnUnlock", - "displayName": "专栏文字选择", - "description": "使专栏的文字可以选择.", + "displayName": "专栏复制优化", + "description": "(原名: 专栏文字选择, 现在专栏已经不限制选中文字了)\r\n\r\n避免专栏的文字复制后在最后带上出处信息, 更贴近原生的复制行为.\r\n", "fullRelativePath": "../../registry/dist/components/utils/column-unlock.js", "fullAbsolutePath": "registry/dist/components/utils/column-unlock.js" }, diff --git a/doc/features/pack/pack.md b/doc/features/pack/pack.md index d72ed0380..08604ae2c 100644 --- a/doc/features/pack/pack.md +++ b/doc/features/pack/pack.md @@ -84,7 +84,7 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist 支持下载各种内容. 包含以下功能: -下载视频, 下载字幕, 下载弹幕, 下载音频, 直播录像下载 +下载视频, 下载字幕, 下载弹幕, 下载音频
jsDelivr Stable @@ -94,7 +94,6 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/subtitle/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/danmaku/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/utils/download-audio.js -https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/live/download-records.js ```
@@ -106,7 +105,6 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/subtitle/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/danmaku/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/utils/download-audio.js -https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/live/download-records.js ``` @@ -118,7 +116,6 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/subtitle/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/danmaku/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/utils/download-audio.js -https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/live/download-records.js ``` @@ -130,7 +127,6 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/subtitle/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/danmaku/download.js https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/utils/download-audio.js -https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/live/download-records.js ``` @@ -139,7 +135,7 @@ https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist 提供一些常用功能. 包含以下功能: -使用细滚动条, 自定义顶栏, 删除广告, 专栏文字选择, 网址参数清理, 快捷键扩展, 查看封面, BV 号转换, 删除直播水印, 直播弹幕发送栏, 直播全屏包裹, 展开动态内容, 动态反折叠, 快速收起评论, 禁止跳转动态详情, 展开视频简介, 设置面板 - "最近使用" 类别 +使用细滚动条, 自定义顶栏, 删除广告, 专栏复制优化, 网址参数清理, 快捷键扩展, 查看封面, BV 号转换, 删除直播水印, 直播弹幕发送栏, 直播全屏包裹, 展开动态内容, 动态反折叠, 快速收起评论, 禁止跳转动态详情, 展开视频简介, 设置面板 - "最近使用" 类别
jsDelivr Stable From b541e1848fa78dbfb6ed307251fb2c4bb6211f79 Mon Sep 17 00:00:00 2001 From: the1812 Date: Sun, 26 Mar 2023 15:06:41 +0800 Subject: [PATCH 52/52] Update docs --- doc/features/features.json | 50 +++++++++++++++++++++++++++++++++- doc/features/features.md | 54 +++++++++++++++++++++++++++++++++++++ doc/features/pack/pack.json | 2 +- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/doc/features/features.json b/doc/features/features.json index 8d2e98006..f3a470b37 100644 --- a/doc/features/features.json +++ b/doc/features/features.json @@ -215,6 +215,14 @@ "fullRelativePath": "../../registry/dist/components/style/hide/banner.js", "fullAbsolutePath": "registry/dist/components/style/hide/banner.js" }, + { + "type": "component", + "name": "hideTrendingSearch", + "displayName": "隐藏热搜", + "description": "隐藏搜索栏和搜索页面中的 `bilibili 热搜`.", + "fullRelativePath": "../../registry/dist/components/style/hide/trending-search.js", + "fullAbsolutePath": "registry/dist/components/style/hide/trending-search.js" + }, { "type": "component", "name": "hideRecommendedLive", @@ -231,6 +239,14 @@ "fullRelativePath": "../../registry/dist/components/style/hide/video/related-videos.js", "fullAbsolutePath": "registry/dist/components/style/hide/video/related-videos.js" }, + { + "type": "component", + "name": "hideVideoShare", + "displayName": "隐藏视频分享", + "description": "隐藏视频和番剧播放器下方的分享按钮.\r\n", + "fullRelativePath": "../../registry/dist/components/style/hide/video/share.js", + "fullAbsolutePath": "registry/dist/components/style/hide/video/share.js" + }, { "type": "component", "name": "hideVideoTopMask", @@ -475,7 +491,7 @@ "type": "component", "name": "urlParamsClean", "displayName": "网址参数清理", - "description": "自动删除网址中的多余跟踪参数. 请注意这会导致浏览器历史记录出现重复的标题 (分别是转换前后的网址), 并可能导致后退要多退几次.", + "description": "自动删除网址中的多余跟踪参数. 请注意这会导致浏览器历史记录出现重复的标题 (分别是转换前后的网址), 并可能导致后退要多退几次.\r\n", "fullRelativePath": "../../registry/dist/components/utils/url-params-clean.js", "fullAbsolutePath": "registry/dist/components/utils/url-params-clean.js" }, @@ -768,6 +784,30 @@ "description": "by FoundTheWOUT\n\n在视频播放器右上角显示系统时间.", "owner": "FoundTheWOUT" }, + { + "type": "plugin", + "name": "launchBar.actions.audioSearch", + "displayName": "搜索栏 - 音频跳转", + "description": "在输入音频的 au 号或播放列表的 am 号时, 提供对应的跳转选项.\r\n", + "fullRelativePath": "../../registry/dist/plugins/launch-bar/audio-search.js", + "fullAbsolutePath": "registry/dist/plugins/launch-bar/audio-search.js" + }, + { + "type": "plugin", + "name": "launchBar.actions.bangumiSearch", + "displayName": "搜索栏 - 番剧跳转", + "description": "在输入番剧的 ss 号 / ep 号, 或番剧详情的 md 号时, 提供对应的跳转选项.\r\n", + "fullRelativePath": "../../registry/dist/plugins/launch-bar/bangumi-search.js", + "fullAbsolutePath": "registry/dist/plugins/launch-bar/bangumi-search.js" + }, + { + "type": "plugin", + "name": "launchBar.actions.cvSearch", + "displayName": "搜索栏 - 专栏跳转", + "description": "在输入专栏的 cv 号或专栏文集的 rl 号时, 提供对应的跳转选项.\r\n", + "fullRelativePath": "../../registry/dist/plugins/launch-bar/cv-search.js", + "fullAbsolutePath": "registry/dist/plugins/launch-bar/cv-search.js" + }, { "type": "plugin", "name": "launchBar.trendingSearch", @@ -824,6 +864,14 @@ "fullRelativePath": "../../registry/dist/plugins/utils/keymap-toggle-danmaku-list.js", "fullAbsolutePath": "registry/dist/plugins/utils/keymap-toggle-danmaku-list.js" }, + { + "type": "plugin", + "name": "keymap.actions.togglePlayerLight", + "displayName": "快捷键扩展 - 开关灯", + "description": "在快捷键的动作列表里添加一个 \"开关灯\".", + "fullRelativePath": "../../registry/dist/plugins/utils/keymap-toggle-player-light.js", + "fullAbsolutePath": "registry/dist/plugins/utils/keymap-toggle-player-light.js" + }, { "type": "plugin", "name": "keymap.actions.toggleSubtitle", diff --git a/doc/features/features.md b/doc/features/features.md index a72ccdfb4..e7c9bfc70 100644 --- a/doc/features/features.md +++ b/doc/features/features.md @@ -255,6 +255,15 @@ 隐藏首页顶部横幅. +### [隐藏热搜](../../registry/dist/components/style/hide/trending-search.js) +`hideTrendingSearch` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/style/hide/trending-search.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/style/hide/trending-search.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/style/hide/trending-search.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/style/hide/trending-search.js) + +隐藏搜索栏和搜索页面中的 `bilibili 热搜`. + ### [隐藏直播推荐](../../registry/dist/components/style/hide/video/recommended-live.js) `hideRecommendedLive` @@ -273,6 +282,15 @@ 隐藏番剧和视频页面右侧的推荐视频列表. 注意: 如果你想关闭 b 站的自动连播 (自动播放下一个推荐视频) 功能, 需要先取消隐藏视频推荐才能看到开关. +### [隐藏视频分享](../../registry/dist/components/style/hide/video/share.js) +`hideVideoShare` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/style/hide/video/share.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/style/hide/video/share.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/style/hide/video/share.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/style/hide/video/share.js) + +隐藏视频和番剧播放器下方的分享按钮. + ### [隐藏视频标题层](../../registry/dist/components/style/hide/video/top-mask.js) `hideVideoTopMask` @@ -1017,6 +1035,33 @@ by FoundTheWOUT 在视频播放器右上角显示系统时间. ## 插件 +### [搜索栏 - 音频跳转](../../registry/dist/plugins/launch-bar/audio-search.js) +`launchBar.actions.audioSearch` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/plugins/launch-bar/audio-search.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/plugins/launch-bar/audio-search.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/plugins/launch-bar/audio-search.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/plugins/launch-bar/audio-search.js) + +在输入音频的 au 号或播放列表的 am 号时, 提供对应的跳转选项. + +### [搜索栏 - 番剧跳转](../../registry/dist/plugins/launch-bar/bangumi-search.js) +`launchBar.actions.bangumiSearch` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/plugins/launch-bar/bangumi-search.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/plugins/launch-bar/bangumi-search.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/plugins/launch-bar/bangumi-search.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/plugins/launch-bar/bangumi-search.js) + +在输入番剧的 ss 号 / ep 号, 或番剧详情的 md 号时, 提供对应的跳转选项. + +### [搜索栏 - 专栏跳转](../../registry/dist/plugins/launch-bar/cv-search.js) +`launchBar.actions.cvSearch` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/plugins/launch-bar/cv-search.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/plugins/launch-bar/cv-search.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/plugins/launch-bar/cv-search.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/plugins/launch-bar/cv-search.js) + +在输入专栏的 cv 号或专栏文集的 rl 号时, 提供对应的跳转选项. + ### [搜索栏 - 搜索推荐](../../registry/dist/plugins/launch-bar/trending-search.js) `launchBar.trendingSearch` @@ -1080,6 +1125,15 @@ by FoundTheWOUT 在快捷键的动作列表里添加一个 "开关弹幕列表". +### [快捷键扩展 - 开关灯](../../registry/dist/plugins/utils/keymap-toggle-player-light.js) +`keymap.actions.togglePlayerLight` + +**jsDelivr:** [`Stable`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/plugins/utils/keymap-toggle-player-light.js) / [`Preview`](https://fastly.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/plugins/utils/keymap-toggle-player-light.js) + +**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/plugins/utils/keymap-toggle-player-light.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/plugins/utils/keymap-toggle-player-light.js) + +在快捷键的动作列表里添加一个 "开关灯". + ### [快捷键扩展 - 开关 CC 字幕](../../registry/dist/plugins/utils/keymap-toggle-subtitle.js) `keymap.actions.toggleSubtitle` diff --git a/doc/features/pack/pack.json b/doc/features/pack/pack.json index 1883bc0bf..ecf335f80 100644 --- a/doc/features/pack/pack.json +++ b/doc/features/pack/pack.json @@ -216,7 +216,7 @@ "type": "component", "name": "urlParamsClean", "displayName": "网址参数清理", - "description": "自动删除网址中的多余跟踪参数. 请注意这会导致浏览器历史记录出现重复的标题 (分别是转换前后的网址), 并可能导致后退要多退几次.", + "description": "自动删除网址中的多余跟踪参数. 请注意这会导致浏览器历史记录出现重复的标题 (分别是转换前后的网址), 并可能导致后退要多退几次.\r\n", "fullRelativePath": "../../registry/dist/components/utils/url-params-clean.js", "fullAbsolutePath": "registry/dist/components/utils/url-params-clean.js" },