diff --git a/registry/lib/components/style/special-danmaku/index.md b/registry/lib/components/style/special-danmaku/index.md new file mode 100644 index 000000000..ef4443db6 --- /dev/null +++ b/registry/lib/components/style/special-danmaku/index.md @@ -0,0 +1 @@ +移除高赞弹幕或 UP 主弹幕的特殊样式, 弹幕内容不会移除. diff --git a/registry/lib/components/style/special-danmaku/index.ts b/registry/lib/components/style/special-danmaku/index.ts index 142bd9385..21e8cae66 100644 --- a/registry/lib/components/style/special-danmaku/index.ts +++ b/registry/lib/components/style/special-danmaku/index.ts @@ -6,6 +6,38 @@ import { import { ComponentEntry } from '@/components/types' import { playerUrls } from '@/core/utils/urls' import { addComponentListener } from '@/core/settings' +import { watchLocalStorage } from '@/core/local-storage' + +enum DanmakuBorderStyle { + Heavy, + Stroke, + Shadow, +} +const danmakuTextShadowMap = { + [DanmakuBorderStyle.Heavy]: + '1px 0 1px #000000,0 1px 1px #000000,0 -1px 1px #000000,-1px 0 1px #000000', + [DanmakuBorderStyle.Stroke]: '0px 0px 1px #000000,0 0 1px #000000,0 0 1px #000000', + [DanmakuBorderStyle.Shadow]: '1px 1px 2px #000000,0 0 1px #000000', +} +const watchDanmakuBorderSettings = () => { + const localStorageKey = 'bpx_player_profile' + const updateDanmakuTextShadow = (playerSettings: any) => { + const danmakuBorderStyle: DanmakuBorderStyle = lodash.get( + playerSettings, + 'dmSetting.fontborder', + ) + document.documentElement.style.setProperty( + '--danmaku-text-shadow', + danmakuTextShadowMap[danmakuBorderStyle], + ) + } + updateDanmakuTextShadow(JSON.parse(localStorage.getItem(localStorageKey))) + watchLocalStorage((key, value) => { + if (key === localStorageKey) { + updateDanmakuTextShadow(JSON.parse(value)) + } + }) +} const options = defineOptionsMetadata({ highlight: { @@ -16,6 +48,10 @@ const options = defineOptionsMetadata({ displayName: '禁用UP主弹幕', defaultValue: true, }, + vip: { + displayName: '禁用大会员弹幕', + defaultValue: true, + }, }) type Options = OptionsOfMetadata @@ -30,6 +66,7 @@ const entry: ComponentEntry = ({ metadata, settings }) => { true, ) }) + watchDanmakuBorderSettings() } const name = 'disableSpecialDanmaku' @@ -45,8 +82,5 @@ export const component = defineComponentMetadata({ }, ], urlInclude: playerUrls, - description: { - 'zh-CN': '移除高赞弹幕或 UP 主弹幕的特殊样式, 弹幕内容不会移除.', - }, options, }) diff --git a/registry/lib/components/style/special-danmaku/special-danmaku.scss b/registry/lib/components/style/special-danmaku/special-danmaku.scss index aff243359..135fbb94c 100644 --- a/registry/lib/components/style/special-danmaku/special-danmaku.scss +++ b/registry/lib/components/style/special-danmaku/special-danmaku.scss @@ -28,3 +28,12 @@ body.disable-up-danmaku-style { } } } +body.disable-vip-danmaku-style { + .bili-dm-vip { + display: contents !important; + text-shadow: inherit !important; + } + .bili-dm:not([style*='--textShadow']) { + --textShadow: var(--danmaku-text-shadow); + } +} diff --git a/src/core/local-storage.ts b/src/core/local-storage.ts index df839fd52..7af471436 100644 --- a/src/core/local-storage.ts +++ b/src/core/local-storage.ts @@ -1,5 +1,5 @@ import { select } from './spin-query' -import { deleteValue, getRandomId } from './utils' +import { createPostHook, deleteValue, getRandomId } from './utils' interface CrossOriginMessage { type: string @@ -132,3 +132,33 @@ export const crossOriginLocalStorage = { }) }, } + +type LocalStorageListener = (key: string, value: string) => void +const localStorageListeners: LocalStorageListener[] = [] +let currentWindowLocalStorageHooked = false + +/** + * 添加对 LocalStorage 的变化监听, 支持当前 window 和同源的其他 window 产生的 LocalStorage 变化 + * @param onLocalStorageUpdate LocalStorage 变化回调 + * @returns 取消监听的函数 + */ +export const watchLocalStorage = (onLocalStorageUpdate: LocalStorageListener) => { + if (!currentWindowLocalStorageHooked) { + createPostHook(unsafeWindow.localStorage, 'setItem', (key: string, value: string) => { + localStorageListeners.forEach(listener => listener(key, value)) + }) + currentWindowLocalStorageHooked = true + } + localStorageListeners.push(onLocalStorageUpdate) + const otherWindowLocalStorageListener = (e: StorageEvent) => { + onLocalStorageUpdate(e.key, e.newValue) + } + window.addEventListener('storage', otherWindowLocalStorageListener) + return () => { + const index = localStorageListeners.indexOf(onLocalStorageUpdate) + if (index > -1) { + localStorageListeners.splice(index, 1) + } + window.removeEventListener('storage', otherWindowLocalStorageListener) + } +}