mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Merge branch 'preview-features' into preview
This commit is contained in:
commit
3fad1960d9
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -102,6 +102,7 @@
|
||||
"tagid",
|
||||
"Tampermonkey",
|
||||
"Touhou",
|
||||
"trendings",
|
||||
"truetype",
|
||||
"uname",
|
||||
"usercard",
|
||||
|
||||
63
CHANGELOG.md
63
CHANGELOG.md
@ -1,6 +1,69 @@
|
||||
<!-- spell-checker: disable -->
|
||||
# 更新日志
|
||||
|
||||
## v2.10.3-preview
|
||||
|
||||
包含 [v2.10.3](https://github.com/the1812/Bilibili-Evolved/releases/tag/v2.10.3) 的所有更新内容.
|
||||
|
||||
- 新增 `深色模式` 组件, 用于跟随 b 站官方的内测深色模式. (#5272)
|
||||
> 脚本自身的元素配色也会逐步适配官方的配色, 目前仅适配设置面板、自定义顶栏和动态首页中的元素
|
||||
|
||||
- `插件 - 下载视频 - WASM 混流输出` 修正下载限制为 2GB, 新增下载速度和剩余时间显示. (#5102, PR #5233 by [WakelessSloth56](https://github.com/WakelessSloth56))
|
||||
- `弹幕空降` 支持识别中文数字, 修复对特殊弹幕未触发的问题. (PR #5265 by [fixfeat](https://github.com/fixfeat))
|
||||
- 新增 `视频预览放大` 组件. (PR #5281 by [wsgh0202](https://github.com/wsgh0202))
|
||||
> 放大鼠标悬停于视频卡片时播放的 5 分钟预览
|
||||
>
|
||||
> - 点击放大镜图标放大预览
|
||||
> - 点击缩小图标或者预览框外空白处关闭预览
|
||||
|
||||
- 修复 `隐藏首页轮播图` 失效, 并增加了一些局部元素控制功能. (PR #5287 [wsgh0202](https://github.com/wsgh0202))
|
||||
|
||||
|
||||
## v2.10.3
|
||||
`2025-07-22`
|
||||
|
||||
<details>
|
||||
<summary>正式版用户将获得 v2.10.1-preview ~ v2.10.2-preview 的所有改动, 点击展开查看</summary>
|
||||
|
||||
- 新增 `稍后再看页面-重定向` 组件. (PR #5205 by [undefined](https://github.com/magicFeirl))
|
||||
> 重定向**稍后再看页面**到普通视频页面,和`稍后再看重定向`组件的区别在于,该组件是在进入稍后再看的视频页面后进行重定向,而非直接替换链接到普通视频的链接,用于补充`稍后再看重定向`组件的功能。
|
||||
|
||||
- `隐藏热搜` 支持隐藏直播间搜索框的热搜. (PR #5207 by [undefined](https://github.com/magicFeirl))
|
||||
- 修复 `视频链接增强` 对 niconico 链接的处理. (PR #5215 by [Alan Ye](https://github.com/at-wr))
|
||||
- 新增 `动态分组过滤` 组件. (PR #5217 by [Rinne](https://github.com/OharaRinneY))
|
||||
> 按照关注分组筛选动态
|
||||
|
||||
- `直播信息扩充` 支持配置置顶和隐藏的关注列表. (#5183)
|
||||
- 新增组件 `一键点亮直播间粉丝勋章`. (PR #5171 by [undefined](https://github.com/magicFeirl))
|
||||
> 在直播间页面的功能面板添加一键点亮粉丝勋章功能,仅适用于有粉丝勋章且正在直播的直播间。原理:发送一个 300 次点赞的请求点亮粉丝勋章。
|
||||
|
||||
- 新增组件 `下载表情`. (PR #5176 by [Pencil](https://github.com/pencilqaq))
|
||||
> 支持下载 up 主专属表情包,处于任意直播间页面时,下载按钮会在 `功能` 面板显示,以压缩包形式保存。
|
||||
|
||||
- 新增组件 `视频链接增强`. (PR #5197 by [Alan Ye](https://github.com/at-wr))
|
||||
> 这个组件会将视频简介中的普通网址转换为可点击的链接,并将<del>被 Bilibili 抛弃</del>已失效的 `acg.tv` 跳转链接修复为 `nicovideo.jp` 链接。
|
||||
>
|
||||
> 例如: `https://acg.tv/sm37507315` → `https://www.nicovideo.jp/watch/sm37507315`
|
||||
>
|
||||
> <i>本组件不会保证目标链接的安全性,因此在点击前请自行验证其是否可信</i>
|
||||
|
||||
- `自定义顶栏` 新增 `使用主题色 Logo` 选项, 关闭时可以使用黑白纯色的 Logo. (#4996)
|
||||
- `自定义顶栏` 更新 `游戏中心`, `漫画`, `赛事` 的弹窗, 废弃 `直播` 的弹窗. (#5055)
|
||||
|
||||
</details>
|
||||
|
||||
(以下其实都是 6 月就更新了, 只要你的 `自动更新器` 正常使用, 应该早已收到更新了, 这些改动无需更新本体)
|
||||
|
||||
✨新增
|
||||
- `显示视频投稿时间` 支持在合集类页面显示. (#5247, PR #5266 by [呼乎户](https://github.com/wisokey))
|
||||
- `动态过滤` 支持过滤新出现的热搜面板. (#5273, PR #5276 by [Whalko](https://github.com/RtYkk))
|
||||
|
||||
🐛修复
|
||||
- 修复 `夜间模式` 在首页 svg 图标的颜色. (PR #5240 by [hyrious](https://github.com/hyrious))
|
||||
- 修复 `自动移出稍后再看` 重复调用接口的 bug. (PR #5241 by [sunfkny](https://github.com/sunfkny))
|
||||
- 修复 `关注时间显示` 失效. (#5096, #5212, PR 5282 by [CNOCM](https://github.com/CNOCM))
|
||||
|
||||
|
||||
## v2.10.2-preview
|
||||
`2025-05-30`
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
## 最低配置
|
||||
- 操作系统: Windows 8.1 / macOS Big Sur
|
||||
- 分辨率: 1920x1080, 缩放 125%
|
||||
- 浏览器: Chrome 105+ / Firefox 127+ / Safari 15.4+ (仅理论上能运行, 没测试过)
|
||||
- 浏览器: Chrome 105+ / Firefox 140+ / Safari 18.4+ (仅理论上能运行, 没测试过)
|
||||
- 处理器: Intel Core i5-10500 / AMD Ryzen 5 3600
|
||||
- 内存: 8GB
|
||||
- 脚本管理器: Tampermonkey 5.0 / Violentmonkey 2.18
|
||||
@ -84,7 +84,7 @@
|
||||
## 推荐配置
|
||||
- 操作系统: Windows 10 / macOS Sonoma
|
||||
- 分辨率: 3840x2160, 缩放 200%
|
||||
- 浏览器: Chrome 120+ / Firefox 127+
|
||||
- 浏览器: Chrome 120+ / Firefox 140+
|
||||
- 处理器: Intel Core i7-11700 / AMD Ryzen 7 5800
|
||||
- 内存: 32GB
|
||||
- 脚本管理器: Tampermonkey 5.0 / Violentmonkey 2.18
|
||||
|
||||
@ -30,6 +30,9 @@ https://afdian.com/a/the1812?tab=sponsor
|
||||
|
||||
| 时间 | 用户名 | 单号后4位 | 金额 |
|
||||
| ------------------- | --------------------- | --------- | ------- |
|
||||
| 2025.07.12 16:44:24 | 爱音allin | 3957 | ¥5.00 |
|
||||
| 2025.06.29 10:53:44 | f*x | 9352 | ¥10.00 |
|
||||
| 2025.06.10 01:22:23 | *匆 | 5332 | ¥5.00 |
|
||||
| 2025.05.21 19:55:02 | mobmaster69 | 7644 | ¥5.00 |
|
||||
| 2025.05.20 02:38:45 | Duane | 3937 | ¥5.00 |
|
||||
| 2025.05.15 22:12:22 | 匿名 | 3901 | ¥23.33 |
|
||||
|
||||
@ -279,6 +279,14 @@
|
||||
"fullRelativePath": "../../registry/dist/components/style/dark-mode.js",
|
||||
"fullAbsolutePath": "registry/dist/components/style/dark-mode.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "integratedDarkMode",
|
||||
"displayName": "深色模式",
|
||||
"description": "简化版的夜间模式,跟随 b 站官方的深色主题。\r\n",
|
||||
"fullRelativePath": "../../registry/dist/components/style/dark-mode/integrated.js",
|
||||
"fullAbsolutePath": "registry/dist/components/style/dark-mode/integrated.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "darkModeSchedule",
|
||||
@ -315,7 +323,7 @@
|
||||
"type": "component",
|
||||
"name": "hideHomeCarousel",
|
||||
"displayName": "隐藏首页轮播图",
|
||||
"description": "隐藏首页的轮播图区域.\r\n",
|
||||
"description": "隐藏首页的轮播图区域\r\n\r\n选项说明:\r\n\r\n- `禁用轮播`:禁用图片轮播,可以手动切换\r\n- `图片模糊`:模糊轮播图片,为0时不模糊\r\n- `样式开关`:\r\n - `隐藏轮播区域占位`:完全隐藏整个轮播区域\r\n - `透明化轮播区域`:完全透明化整个轮播区域,同时禁止点击打开链接\r\n - `隐藏轮播图片`:隐藏轮播图片,同时禁止点击图片打开链接\r\n - `隐藏图片标题`:隐藏图片标题,同时禁止点击标题打开链接\r\n\r\n > 注:样式开关可以同时启用,但是最终显示效果以作用范围大的为准 \r\n > 例如启用 `隐藏轮播区域占位`,由于整个区域都被隐藏,不管 `隐藏轮播图片`、`隐藏图片标题` 等选项是否启用都已经看不见了\r\n",
|
||||
"fullRelativePath": "../../registry/dist/components/style/hide/home-carousel.js",
|
||||
"fullAbsolutePath": "registry/dist/components/style/hide/home-carousel.js"
|
||||
},
|
||||
@ -543,6 +551,14 @@
|
||||
"fullRelativePath": "../../registry/dist/components/utils/auto-like.js",
|
||||
"fullAbsolutePath": "registry/dist/components/utils/auto-like.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "biggerVideoPreview",
|
||||
"displayName": "视频预览放大",
|
||||
"description": "放大鼠标悬停于视频卡片时播放的5分钟预览\r\n\r\n- 点击放大镜图标放大预览\r\n- 点击缩小图标或者预览框外空白处关闭预览\r\n",
|
||||
"fullRelativePath": "../../registry/dist/components/utils/bigger-video-preview.js",
|
||||
"fullAbsolutePath": "registry/dist/components/utils/bigger-video-preview.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "blackList",
|
||||
@ -675,7 +691,7 @@
|
||||
"type": "component",
|
||||
"name": "subscribeTimeShow",
|
||||
"displayName": "关注时间显示",
|
||||
"description": "by [@Light_Quanta](https://github.com/LightQuanta)\n\n在粉丝/关注列表显示关注的具体时间",
|
||||
"description": "by [@CNOCM](https://github.com/CNOCM)\n\n在粉丝/关注列表及用户主页显示关注的具体时间。",
|
||||
"fullRelativePath": "../../registry/dist/components/utils/subscribe-time-show.js",
|
||||
"fullAbsolutePath": "registry/dist/components/utils/subscribe-time-show.js"
|
||||
},
|
||||
|
||||
@ -373,6 +373,15 @@ by [@Tinhone](https://github.com/Tinhone)
|
||||
|
||||
启用夜间模式能更好地适应光线暗的环境, 并会大量应用主题颜色.
|
||||
|
||||
### [深色模式](../../registry/dist/components/style/dark-mode/integrated.js)
|
||||
`integratedDarkMode`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/style/dark-mode/integrated.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/style/dark-mode/integrated.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/style/dark-mode/integrated.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/style/dark-mode/integrated.js)
|
||||
|
||||
简化版的夜间模式,跟随 b 站官方的深色主题。
|
||||
|
||||
### [夜间模式计划时段](../../registry/dist/components/style/dark-mode/schedule.js)
|
||||
`darkModeSchedule`
|
||||
|
||||
@ -416,7 +425,20 @@ by [@Tinhone](https://github.com/Tinhone)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/style/hide/home-carousel.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/style/hide/home-carousel.js)
|
||||
|
||||
隐藏首页的轮播图区域.
|
||||
隐藏首页的轮播图区域
|
||||
|
||||
选项说明:
|
||||
|
||||
- `禁用轮播`:禁用图片轮播,可以手动切换
|
||||
- `图片模糊`:模糊轮播图片,为0时不模糊
|
||||
- `样式开关`:
|
||||
- `隐藏轮播区域占位`:完全隐藏整个轮播区域
|
||||
- `透明化轮播区域`:完全透明化整个轮播区域,同时禁止点击打开链接
|
||||
- `隐藏轮播图片`:隐藏轮播图片,同时禁止点击图片打开链接
|
||||
- `隐藏图片标题`:隐藏图片标题,同时禁止点击标题打开链接
|
||||
|
||||
> 注:样式开关可以同时启用,但是最终显示效果以作用范围大的为准
|
||||
> 例如启用 `隐藏轮播区域占位`,由于整个区域都被隐藏,不管 `隐藏轮播图片`、`隐藏图片标题` 等选项是否启用都已经看不见了
|
||||
|
||||
### [隐藏热搜](../../registry/dist/components/style/hide/trending-search.js)
|
||||
`hideTrendingSearch`
|
||||
@ -719,6 +741,18 @@ by [@CrazyboyQCD](https://github.com/CrazyboyQCD)
|
||||
安装快捷键扩展后可以点击【l】键或【L】键触发\
|
||||
还可以添加动态点赞的黑名单\
|
||||
|
||||
### [视频预览放大](../../registry/dist/components/utils/bigger-video-preview.js)
|
||||
`biggerVideoPreview`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/utils/bigger-video-preview.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/utils/bigger-video-preview.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/utils/bigger-video-preview.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/utils/bigger-video-preview.js)
|
||||
|
||||
放大鼠标悬停于视频卡片时播放的5分钟预览
|
||||
|
||||
- 点击放大镜图标放大预览
|
||||
- 点击缩小图标或者预览框外空白处关闭预览
|
||||
|
||||
### [屏蔽黑名单up主](../../registry/dist/components/utils/black-list.js)
|
||||
`blackList`
|
||||
|
||||
@ -946,9 +980,9 @@ by [@Light_Quanta](https://github.com/LightQuanta)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/utils/subscribe-time-show.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/utils/subscribe-time-show.js)
|
||||
|
||||
by [@Light_Quanta](https://github.com/LightQuanta)
|
||||
by [@CNOCM](https://github.com/CNOCM)
|
||||
|
||||
在粉丝/关注列表显示关注的具体时间
|
||||
在粉丝/关注列表及用户主页显示关注的具体时间。
|
||||
|
||||
### [网址参数清理](../../registry/dist/components/utils/url-params-clean.js)
|
||||
`urlParamsClean`
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
"terser-webpack-plugin": "^5.0.1",
|
||||
"to-string-loader": "^1.2.0",
|
||||
"ts-node": "^10.7.0",
|
||||
"typescript": "^4.9.5",
|
||||
"typescript": "5.8.3",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"vue-loader": "^15.10.1",
|
||||
"webpack": "^5.31.2",
|
||||
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@ -99,10 +99,10 @@ importers:
|
||||
version: 8.5.14
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^5.50.0
|
||||
version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)
|
||||
version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^5.50.0
|
||||
version: 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
version: 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
async-exit-hook:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
@ -123,13 +123,13 @@ importers:
|
||||
version: 7.32.0
|
||||
eslint-config-airbnb-base:
|
||||
specifier: ^14.1.0
|
||||
version: 14.2.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0)
|
||||
version: 14.2.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0))(eslint@7.32.0)
|
||||
eslint-config-prettier:
|
||||
specifier: ^8.6.0
|
||||
version: 8.10.0(eslint@7.32.0)
|
||||
eslint-plugin-import:
|
||||
specifier: ^2.20.1
|
||||
version: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)
|
||||
version: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
@ -177,10 +177,10 @@ importers:
|
||||
version: 1.2.0
|
||||
ts-node:
|
||||
specifier: ^10.7.0
|
||||
version: 10.9.2(@types/node@17.0.45)(typescript@4.9.5)
|
||||
version: 10.9.2(@types/node@17.0.45)(typescript@5.8.3)
|
||||
typescript:
|
||||
specifier: ^4.9.5
|
||||
version: 4.9.5
|
||||
specifier: 5.8.3
|
||||
version: 5.8.3
|
||||
vue-eslint-parser:
|
||||
specifier: ^9.4.3
|
||||
version: 9.4.3(eslint@7.32.0)
|
||||
@ -3540,9 +3540,9 @@ packages:
|
||||
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typescript@4.9.5:
|
||||
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
typescript@5.8.3:
|
||||
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
@ -4803,34 +4803,34 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
|
||||
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)':
|
||||
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
'@typescript-eslint/scope-manager': 5.62.0
|
||||
'@typescript-eslint/type-utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/type-utils': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
debug: 4.4.0
|
||||
eslint: 7.32.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.2
|
||||
natural-compare-lite: 1.4.0
|
||||
semver: 7.7.1
|
||||
tsutils: 3.21.0(typescript@4.9.5)
|
||||
tsutils: 3.21.0(typescript@5.8.3)
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5)':
|
||||
'@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 5.62.0
|
||||
'@typescript-eslint/types': 5.62.0
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5)
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3)
|
||||
debug: 4.4.0
|
||||
eslint: 7.32.0
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -4839,21 +4839,21 @@ snapshots:
|
||||
'@typescript-eslint/types': 5.62.0
|
||||
'@typescript-eslint/visitor-keys': 5.62.0
|
||||
|
||||
'@typescript-eslint/type-utils@5.62.0(eslint@7.32.0)(typescript@4.9.5)':
|
||||
'@typescript-eslint/type-utils@5.62.0(eslint@7.32.0)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5)
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
debug: 4.4.0
|
||||
eslint: 7.32.0
|
||||
tsutils: 3.21.0(typescript@4.9.5)
|
||||
tsutils: 3.21.0(typescript@5.8.3)
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/types@5.62.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)':
|
||||
'@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 5.62.0
|
||||
'@typescript-eslint/visitor-keys': 5.62.0
|
||||
@ -4861,20 +4861,20 @@ snapshots:
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.7.1
|
||||
tsutils: 3.21.0(typescript@4.9.5)
|
||||
tsutils: 3.21.0(typescript@5.8.3)
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@5.62.0(eslint@7.32.0)(typescript@4.9.5)':
|
||||
'@typescript-eslint/utils@5.62.0(eslint@7.32.0)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@7.32.0)
|
||||
'@types/json-schema': 7.0.15
|
||||
'@types/semver': 7.5.8
|
||||
'@typescript-eslint/scope-manager': 5.62.0
|
||||
'@typescript-eslint/types': 5.62.0
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5)
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3)
|
||||
eslint: 7.32.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.7.1
|
||||
@ -5683,11 +5683,11 @@ snapshots:
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-airbnb-base@14.2.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0):
|
||||
eslint-config-airbnb-base@14.2.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0))(eslint@7.32.0):
|
||||
dependencies:
|
||||
confusing-browser-globals: 1.0.11
|
||||
eslint: 7.32.0
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)
|
||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)
|
||||
object.assign: 4.1.7
|
||||
object.entries: 1.1.8
|
||||
|
||||
@ -5703,17 +5703,17 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@7.32.0):
|
||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@7.32.0):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
eslint: 7.32.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0):
|
||||
eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.8
|
||||
@ -5724,7 +5724,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 7.32.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@7.32.0)
|
||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@7.32.0)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
@ -5736,7 +5736,7 @@ snapshots:
|
||||
string.prototype.trimend: 1.0.9
|
||||
tsconfig-paths: 3.15.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
@ -7382,7 +7382,7 @@ snapshots:
|
||||
|
||||
totalist@3.0.1: {}
|
||||
|
||||
ts-node@10.9.2(@types/node@17.0.45)(typescript@4.9.5):
|
||||
ts-node@10.9.2(@types/node@17.0.45)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
@ -7396,7 +7396,7 @@ snapshots:
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
|
||||
@ -7409,10 +7409,10 @@ snapshots:
|
||||
|
||||
tslib@1.14.1: {}
|
||||
|
||||
tsutils@3.21.0(typescript@4.9.5):
|
||||
tsutils@3.21.0(typescript@5.8.3):
|
||||
dependencies:
|
||||
tslib: 1.14.1
|
||||
typescript: 4.9.5
|
||||
typescript: 5.8.3
|
||||
|
||||
type-check@0.4.0:
|
||||
dependencies:
|
||||
@ -7453,7 +7453,7 @@ snapshots:
|
||||
possible-typed-array-names: 1.1.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typescript@4.9.5: {}
|
||||
typescript@5.8.3: {}
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
dependencies:
|
||||
|
||||
@ -239,8 +239,8 @@ onBeforeUnmount(() => {
|
||||
background-color: #fff;
|
||||
|
||||
body.dark & {
|
||||
background-color: #444;
|
||||
color: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
background-color: var(--be-color-popup-bg, #444);
|
||||
}
|
||||
|
||||
&-header {
|
||||
@ -327,7 +327,7 @@ onBeforeUnmount(() => {
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
border: 1px solid #8884;
|
||||
border: 1px solid var(--be-color-avatar-border, #8884);
|
||||
}
|
||||
|
||||
&-info {
|
||||
|
||||
@ -33,23 +33,20 @@
|
||||
</div>
|
||||
<h2>板块</h2>
|
||||
<div class="filter-side-card">
|
||||
<div
|
||||
<FilterSideCard
|
||||
v-for="[id, type] of Object.entries(allSideCards)"
|
||||
:id="parseInt(id)"
|
||||
:key="id"
|
||||
class="filter-side-card-switch feeds-filter-switch"
|
||||
@click="toggleBlockSide(id)"
|
||||
>
|
||||
<label :class="{ disabled: sideDisabled(id) }">
|
||||
<span class="name" :class="{ disabled: sideDisabled(id) }">{{ type.displayName }}</span>
|
||||
<VIcon :size="16" class="disabled" icon="mdi-cancel"></VIcon>
|
||||
<VIcon :size="16" icon="mdi-check"></VIcon>
|
||||
</label>
|
||||
</div>
|
||||
:name="type.displayName"
|
||||
:block-side-cards="blockSideCards"
|
||||
@click="toggleBlockSide(parseInt(id))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, onMounted, defineAsyncComponent } from 'vue'
|
||||
import {
|
||||
FeedsCard,
|
||||
FeedsCardType,
|
||||
@ -64,11 +61,16 @@ import { VIcon, TextBox, VButton } from '@/ui'
|
||||
import { FeedsFilterOptions } from './options'
|
||||
import { hasBlockedPattern } from './pattern'
|
||||
|
||||
const FilterTypeSwitch = defineAsyncComponent(() => import('./FilterTypeSwitch.vue'))
|
||||
const FilterSideCard = defineAsyncComponent(() => import('./FilterSideCard.vue'))
|
||||
|
||||
const { options } = getComponentSettings<FeedsFilterOptions>('feedsFilter')
|
||||
|
||||
interface SideCardType {
|
||||
className: string
|
||||
displayName: string
|
||||
}
|
||||
|
||||
const sideCards: { [id: number]: SideCardType } = {
|
||||
0: {
|
||||
className: 'profile',
|
||||
@ -103,126 +105,120 @@ const sideCards: { [id: number]: SideCardType } = {
|
||||
displayName: '热搜',
|
||||
},
|
||||
}
|
||||
|
||||
if (getComponentSettings('extendFeedsLive').enabled) {
|
||||
delete sideCards[3]
|
||||
}
|
||||
|
||||
let cardsManager: typeof import('@/components/feeds/api').feedsCardsManager
|
||||
const sideBlock = 'feeds-filter-side-block-'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
FilterTypeSwitch: () => import('./FilterTypeSwitch.vue'),
|
||||
VIcon,
|
||||
TextBox,
|
||||
VButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
allTypes: [] as [string, FeedsCardType][],
|
||||
patterns: [...options.patterns],
|
||||
newPattern: '',
|
||||
allSideCards: sideCards,
|
||||
blockSideCards: [...options.sideCards],
|
||||
collapse: true,
|
||||
const allTypes = ref<[string, FeedsCardType][]>([])
|
||||
const patterns = reactive([...options.patterns])
|
||||
const newPattern = ref('')
|
||||
const allSideCards = reactive(sideCards)
|
||||
const blockSideCards = reactive([...options.sideCards])
|
||||
const collapse = ref(true)
|
||||
|
||||
const updateCard = (card: FeedsCard) => {
|
||||
const blockableCard = {
|
||||
...card,
|
||||
}
|
||||
if (card.type === feedsCardTypes.repost) {
|
||||
blockableCard.text += `\n${(card as RepostFeedsCard).repostText}`
|
||||
}
|
||||
const block = options.patterns.some(p => hasBlockedPattern(p, blockableCard))
|
||||
if (block) {
|
||||
card.element.classList.add('pattern-block')
|
||||
} else {
|
||||
card.element.classList.remove('pattern-block')
|
||||
}
|
||||
}
|
||||
|
||||
watch(patterns, () => {
|
||||
options.patterns = patterns
|
||||
if (cardsManager) {
|
||||
cardsManager.cards.forEach(card => updateCard(lodash.clone(card)))
|
||||
}
|
||||
})
|
||||
|
||||
const deletePattern = (pattern: string) => {
|
||||
const index = patterns.indexOf(pattern)
|
||||
if (index !== -1) {
|
||||
patterns.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const addPattern = (pattern: string) => {
|
||||
if (pattern && !patterns.includes(pattern)) {
|
||||
patterns.push(pattern)
|
||||
}
|
||||
newPattern.value = ''
|
||||
}
|
||||
|
||||
const updateBlockSide = () => {
|
||||
Object.entries(sideCards).forEach(([id, type]) => {
|
||||
const name = sideBlock + type.className
|
||||
if (blockSideCards.includes(parseInt(id))) {
|
||||
document.body.classList.add(name)
|
||||
} else {
|
||||
document.body.classList.remove(name)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
patterns() {
|
||||
options.patterns = this.patterns
|
||||
if (cardsManager) {
|
||||
cardsManager.cards.forEach(card => this.updateCard(lodash.clone(card)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const toggleBlockSide = (id: number) => {
|
||||
const index = blockSideCards.indexOf(id)
|
||||
const type = sideCards[id]
|
||||
if (index !== -1) {
|
||||
blockSideCards.splice(index, 1)
|
||||
document.body.classList.remove(sideBlock + type.className)
|
||||
} else {
|
||||
blockSideCards.push(id)
|
||||
document.body.classList.add(sideBlock + type.className)
|
||||
}
|
||||
options.sideCards = blockSideCards
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
updateBlockSide()
|
||||
const tabBar = await select('.feed-card .tab-bar, .bili-dyn-list-tabs__list')
|
||||
if (!tabBar) {
|
||||
console.error('tabBar not found')
|
||||
return
|
||||
}
|
||||
document.body.classList.add('enable-feeds-filter')
|
||||
const specialTypes = {
|
||||
'self-repost': {
|
||||
id: -1,
|
||||
name: '自转发',
|
||||
} as FeedsCardType,
|
||||
}
|
||||
allTypes.value = Object.entries(feedsCardTypes)
|
||||
.concat(Object.entries(specialTypes))
|
||||
.filter(([, type]) => type.id <= 2048 && type.id !== 0)
|
||||
.map(([name, type]) => [name, lodash.clone(type)])
|
||||
cardsManager = await forEachFeedsCard({
|
||||
added: card => {
|
||||
updateCard(lodash.clone(card))
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.updateBlockSide()
|
||||
const tabBar = await select('.feed-card .tab-bar, .bili-dyn-list-tabs__list')
|
||||
if (!tabBar) {
|
||||
console.error('tabBar not found')
|
||||
return
|
||||
}
|
||||
document.body.classList.add('enable-feeds-filter')
|
||||
const specialTypes = {
|
||||
'self-repost': {
|
||||
id: -1,
|
||||
name: '自转发',
|
||||
} as FeedsCardType,
|
||||
}
|
||||
this.allTypes = Object.entries(feedsCardTypes)
|
||||
.concat(Object.entries(specialTypes))
|
||||
.filter(([, type]) => type.id <= 2048 && type.id !== 0)
|
||||
.map(([name, type]) => [name, lodash.clone(type)])
|
||||
cardsManager = await forEachFeedsCard({
|
||||
added: card => {
|
||||
this.updateCard(lodash.clone(card))
|
||||
},
|
||||
})
|
||||
if (cardsManager.managerType === 'v1') {
|
||||
const tab = tabBar.querySelector('.tab:nth-child(1) .tab-text') as HTMLAnchorElement
|
||||
attributes(tab, () => {
|
||||
document.body.classList.toggle('by-type', !tab.classList.contains('selected'))
|
||||
})
|
||||
if (cardsManager.managerType === 'v1') {
|
||||
const tab = tabBar.querySelector('.tab:nth-child(1) .tab-text') as HTMLAnchorElement
|
||||
attributes(tab, () => {
|
||||
document.body.classList.toggle('by-type', !tab.classList.contains('selected'))
|
||||
})
|
||||
}
|
||||
if (cardsManager.managerType === 'v2') {
|
||||
const mainContainer = (await select('.bili-dyn-home--member main')) as HTMLElement
|
||||
/** 类型过滤选中"全部" */
|
||||
const isAllTypesSelected = () => Boolean(dq('.bili-dyn-list-tabs__item:first-child.active'))
|
||||
/** 关注列表选中"全部动态" */
|
||||
const isAllUpsSelected = () => Boolean(dq('.bili-dyn-up-list__item:first-child.active'))
|
||||
attributesSubtree(mainContainer, () => {
|
||||
document.body.classList.toggle('by-type', isAllUpsSelected() && !isAllTypesSelected())
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateCard(card: FeedsCard) {
|
||||
const blockableCard = {
|
||||
...card,
|
||||
}
|
||||
if (card.type === feedsCardTypes.repost) {
|
||||
blockableCard.text += `\n${(card as RepostFeedsCard).repostText}`
|
||||
}
|
||||
const block = options.patterns.some(p => hasBlockedPattern(p, blockableCard))
|
||||
if (block) {
|
||||
card.element.classList.add('pattern-block')
|
||||
} else {
|
||||
card.element.classList.remove('pattern-block')
|
||||
}
|
||||
},
|
||||
deletePattern(pattern: string) {
|
||||
const index = options.patterns.indexOf(pattern)
|
||||
if (index !== -1) {
|
||||
this.patterns.splice(index, 1)
|
||||
}
|
||||
},
|
||||
addPattern(pattern: string) {
|
||||
if (pattern && !this.patterns.includes(pattern)) {
|
||||
this.patterns.push(pattern)
|
||||
}
|
||||
this.newPattern = ''
|
||||
},
|
||||
updateBlockSide() {
|
||||
Object.entries(sideCards).forEach(([id, type]) => {
|
||||
const name = sideBlock + type.className
|
||||
document.body.classList[this.blockSideCards.includes(id) ? 'add' : 'remove'](name)
|
||||
})
|
||||
},
|
||||
toggleBlockSide(id: number) {
|
||||
const index = this.blockSideCards.indexOf(id)
|
||||
const type = sideCards[id]
|
||||
if (index !== -1) {
|
||||
this.blockSideCards.splice(index, 1)
|
||||
document.body.classList.remove(sideBlock + type.className)
|
||||
} else {
|
||||
this.blockSideCards.push(id)
|
||||
document.body.classList.add(sideBlock + type.className)
|
||||
}
|
||||
options.sideCards = this.blockSideCards
|
||||
},
|
||||
sideDisabled(id: number) {
|
||||
return this.blockSideCards.includes(id)
|
||||
},
|
||||
},
|
||||
}
|
||||
if (cardsManager.managerType === 'v2') {
|
||||
const mainContainer = (await select('.bili-dyn-home--member main')) as HTMLElement
|
||||
/** 类型过滤选中"全部" */
|
||||
const isAllTypesSelected = () => Boolean(dq('.bili-dyn-list-tabs__item:first-child.active'))
|
||||
/** 关注列表选中"全部动态" */
|
||||
const isAllUpsSelected = () => Boolean(dq('.bili-dyn-up-list__item:first-child.active'))
|
||||
attributesSubtree(mainContainer, () => {
|
||||
document.body.classList.toggle('by-type', isAllUpsSelected() && !isAllTypesSelected())
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -271,8 +267,8 @@ body.disable-feeds-filter {
|
||||
}
|
||||
}
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
background-color: #444;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
background-color: var(--be-color-panel-bg, #444);
|
||||
}
|
||||
.feeds-filter-header {
|
||||
cursor: pointer;
|
||||
@ -335,7 +331,7 @@ body.disable-feeds-filter {
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #8884;
|
||||
border: 1px solid var(--be-color-card-border, #8884);
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
21
registry/lib/components/feeds/filter/FilterSideCard.vue
Normal file
21
registry/lib/components/feeds/filter/FilterSideCard.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="filter-side-card-switch feeds-filter-switch" v-on="$listeners">
|
||||
<label :class="{ disabled }">
|
||||
<span class="name" :class="{ disabled }">{{ name }}</span>
|
||||
<VIcon :size="16" class="disabled" icon="mdi-cancel"></VIcon>
|
||||
<VIcon :size="16" icon="mdi-check"></VIcon>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { VIcon } from '@/ui'
|
||||
|
||||
const props = defineProps<{
|
||||
blockSideCards: number[]
|
||||
id: number
|
||||
name: string
|
||||
}>()
|
||||
|
||||
const disabled = computed(() => props.blockSideCards.includes(props.id))
|
||||
</script>
|
||||
@ -9,59 +9,56 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted, computed } from 'vue'
|
||||
import { getComponentSettings } from '@/core/settings'
|
||||
import { VIcon } from '@/ui'
|
||||
import { FeedsFilterOptions } from './options'
|
||||
|
||||
interface Props {
|
||||
name: string
|
||||
type: {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const { options } = getComponentSettings<FeedsFilterOptions>('feedsFilter')
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
VIcon,
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const optionKey = this.type.id >= 0 ? 'types' : 'specialTypes'
|
||||
const disabled = options[optionKey].includes(this.type.id)
|
||||
return {
|
||||
disabled,
|
||||
optionKey,
|
||||
|
||||
const optionKey = computed(() => (props.type.id >= 0 ? 'types' : 'specialTypes'))
|
||||
|
||||
const disabled = ref(options[optionKey.value].includes(props.type.id))
|
||||
|
||||
const setFilter = (isDisabled: boolean, updateSettings = true) => {
|
||||
if (isDisabled) {
|
||||
document.body.classList.add(`feeds-filter-block-${props.name}`)
|
||||
} else {
|
||||
document.body.classList.remove(`feeds-filter-block-${props.name}`)
|
||||
}
|
||||
|
||||
if (!updateSettings) {
|
||||
return
|
||||
}
|
||||
|
||||
const key = optionKey.value as 'types' | 'specialTypes'
|
||||
if (isDisabled) {
|
||||
options[key].push(props.type.id)
|
||||
} else {
|
||||
const index = options[key].indexOf(props.type.id)
|
||||
if (index !== -1) {
|
||||
options[key].splice(index, 1)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
disabled(newValue: boolean) {
|
||||
this.setFilter(newValue)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.setFilter(this.disabled, false)
|
||||
},
|
||||
methods: {
|
||||
setFilter(disabled: boolean, updateSettings = true) {
|
||||
document.body.classList[disabled ? 'add' : 'remove'](`feeds-filter-block-${this.name}`)
|
||||
if (!updateSettings) {
|
||||
return
|
||||
}
|
||||
const optionKey = this.optionKey as 'types' | 'specialTypes'
|
||||
if (disabled) {
|
||||
options[optionKey].push(this.type.id)
|
||||
} else {
|
||||
const index = options[optionKey].indexOf(this.type.id)
|
||||
if (index !== -1) {
|
||||
options[optionKey].splice(index, 1)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
watch(disabled, (newValue: boolean) => {
|
||||
setFilter(newValue)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
setFilter(disabled.value, false)
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@ -77,7 +74,7 @@ export default Vue.extend({
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border: 1px solid #8884;
|
||||
border: 1px solid var(--be-color-card-border, #8884);
|
||||
|
||||
.name {
|
||||
font-size: 12px;
|
||||
@ -86,7 +83,7 @@ export default Vue.extend({
|
||||
color: var(--theme-color) !important;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #8882;
|
||||
background-color: var(--be-color-highlight-bg-hover, #8882);
|
||||
}
|
||||
input {
|
||||
display: none;
|
||||
|
||||
@ -19,8 +19,8 @@
|
||||
color: black;
|
||||
}
|
||||
body.dark & {
|
||||
background-color: #444;
|
||||
color: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
background-color: var(--be-color-panel-bg, #444);
|
||||
&:hover {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
|
||||
@ -87,6 +87,11 @@ html {
|
||||
--navbar-bounds-padding: 10%;
|
||||
// --navbar-blur-opacity: 0.7;
|
||||
--navbar-icon-size: 24px;
|
||||
|
||||
--be-color-navbar-bg: var(--bg1);
|
||||
--be-color-navbar-skeleton-bg: var(--bg1_float);
|
||||
--be-color-navbar-shadow: rgba(var(--shadow_rgb), 0.4);
|
||||
--be-color-navbar-bg-blur: rgba(var(--bg1_rgb), 0.8);
|
||||
}
|
||||
|
||||
body.custom-navbar-loading::after {
|
||||
@ -100,7 +105,7 @@ body.custom-navbar-loading::after {
|
||||
z-index: 10001;
|
||||
}
|
||||
body.dark.custom-navbar-loading::after {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-navbar-skeleton-bg, #333);
|
||||
}
|
||||
body.fixed-navbar {
|
||||
.left-panel {
|
||||
@ -182,7 +187,7 @@ body.fixed-navbar {
|
||||
box-shadow: #0002 0 1px 10px 1px;
|
||||
}
|
||||
body.dark &.shadow:not(.transparent) {
|
||||
box-shadow: #0004 0px 2px 10px 1px;
|
||||
box-shadow: var(--be-color-navbar-shadow, #0004) 0px 2px 10px 1px;
|
||||
}
|
||||
|
||||
&.blur:not(.transparent) {
|
||||
@ -191,10 +196,10 @@ body.fixed-navbar {
|
||||
}
|
||||
|
||||
body.dark &:not(.fill):not(.transparent) {
|
||||
--navbar-background: #222;
|
||||
--navbar-background: var(--be-color-navbar-bg, #222);
|
||||
--navbar-foreground: #eee;
|
||||
&.blur {
|
||||
--navbar-background: #2228;
|
||||
--navbar-background: var(--be-color-navbar-bg-blur, #2228);
|
||||
}
|
||||
}
|
||||
&.transparent {
|
||||
|
||||
@ -258,7 +258,7 @@ export default Vue.extend({
|
||||
color: black;
|
||||
background: white;
|
||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid #8882;
|
||||
border: 1px solid var(--be-color-popup-border, #8882);
|
||||
border-radius: 8px;
|
||||
transition: opacity 0.2s ease-out 0.2s;
|
||||
position: absolute;
|
||||
@ -271,8 +271,8 @@ export default Vue.extend({
|
||||
cursor: default;
|
||||
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
background: #222;
|
||||
color: var(--be-color-text-content, #eee);
|
||||
background: var(--be-color-popup-bg, #222);
|
||||
}
|
||||
|
||||
&.iframe-container {
|
||||
|
||||
@ -40,13 +40,13 @@
|
||||
@keyframes transparent-to-dark {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #222;
|
||||
--navbar-background: var(--be-color-navbar-bg, #222);
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark-blur {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #2228;
|
||||
--navbar-background: var(--be-color-navbar-bg-blur, #2228);
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
}
|
||||
@ -81,14 +81,14 @@
|
||||
@keyframes transparent-to-dark-shadow {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #222;
|
||||
--navbar-background: var(--be-color-navbar-bg, #222);
|
||||
box-shadow: #0004 0px 2px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark-blur-shadow {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #2228;
|
||||
--navbar-background: var(--be-color-navbar-bg-blur, #2228);
|
||||
backdrop-filter: blur(24px);
|
||||
box-shadow: #0004 0px 2px 10px 1px;
|
||||
}
|
||||
|
||||
@ -375,8 +375,8 @@ export default Vue.extend({
|
||||
'cover info' 1fr / 130px 1fr;
|
||||
height: 85px;
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #282828);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 12px;
|
||||
|
||||
@ -88,8 +88,8 @@ export default Vue.extend({
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #282828);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
.face-container {
|
||||
flex-shrink: 0;
|
||||
|
||||
@ -156,9 +156,15 @@ defineExpose({
|
||||
.list-game-cards-title {
|
||||
font-size: large;
|
||||
@include semi-bold();
|
||||
body.dark & {
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
}
|
||||
.list-game-cards {
|
||||
@include v-stretch();
|
||||
body.dark & {
|
||||
color: var(--be-color-text-content, #aaa);
|
||||
}
|
||||
.list-game-card {
|
||||
@include single-line();
|
||||
padding: 4px 0;
|
||||
|
||||
@ -361,7 +361,7 @@ export default Vue.extend({
|
||||
z-index: 1;
|
||||
background-color: #fff;
|
||||
body.dark & {
|
||||
background-color: #222;
|
||||
background-color: var(--be-color-popup-bg, #222);
|
||||
}
|
||||
}
|
||||
&-items {
|
||||
@ -392,8 +392,8 @@ export default Vue.extend({
|
||||
border: 1px solid #8882;
|
||||
box-sizing: border-box;
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #282828);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 8px;
|
||||
|
||||
@ -211,7 +211,11 @@ defineExpose({
|
||||
background-image: linear-gradient(to left, #fff 75%, transparent);
|
||||
padding: 18px 18px 18px 60px;
|
||||
body.dark & {
|
||||
background-image: linear-gradient(to left, #222 75%, transparent);
|
||||
background-image: linear-gradient(
|
||||
to left,
|
||||
var(--be-color-popup-bg, #222) 75%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
img {
|
||||
display: flex;
|
||||
|
||||
@ -183,8 +183,8 @@ export default Vue.extend({
|
||||
$radius: 8px;
|
||||
border-radius: $radius;
|
||||
body.dark & {
|
||||
background-color: #2d2d2d;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #2d2d2d);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
.subscriptions-cover-container {
|
||||
height: 64px;
|
||||
|
||||
@ -465,7 +465,7 @@ export default Vue.extend({
|
||||
margin: 5px 10px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
body.dark & {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
background: var(--be-color-panel-border, rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
}
|
||||
.level-icon.plus {
|
||||
@ -531,9 +531,9 @@ export default Vue.extend({
|
||||
}
|
||||
}
|
||||
body.dark & {
|
||||
background: #282828;
|
||||
background-color: var(--be-color-button-bg, #282828);
|
||||
&:hover {
|
||||
background: #333;
|
||||
background-color: var(--be-color-button-bg-hover, #333);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,8 +288,8 @@ export default Vue.extend({
|
||||
'cover info' 1fr / 130px 1fr;
|
||||
height: 85px;
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #282828);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 12px;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
--Ga0: #0d0d0e;
|
||||
--Ga0_s: #1e2022;
|
||||
--Ga0_t: #1e2022;
|
||||
--Ga1: #000000;
|
||||
--Ga1: #000;
|
||||
--Ga1_s: #232527;
|
||||
--Ga1_t: #232527;
|
||||
--Ga1_e: #232527;
|
||||
@ -29,9 +29,9 @@
|
||||
--Ga12: #1f2022;
|
||||
--Wh0: #17181a;
|
||||
--Wh0_t: #17181a;
|
||||
--Ba0: #000000;
|
||||
--Ba0_s: #ffffff;
|
||||
--Ba0_t: #000000;
|
||||
--Ba0: #000;
|
||||
--Ba0_s: #fff;
|
||||
--Ba0_t: #000;
|
||||
--Pi0: #26161c;
|
||||
--Pi1: #2f1a22;
|
||||
--Pi2: #472030;
|
||||
@ -187,6 +187,34 @@
|
||||
--Si8: #c8ced6;
|
||||
--Si9: #dce0e5;
|
||||
--Si10: #f0f2f4;
|
||||
--Pi5_rgb: 212, 78, 125;
|
||||
--Pi1_rgb: 47, 26, 34;
|
||||
--Lb5_rgb: 0, 135, 189;
|
||||
--Lb1_rgb: 11, 32, 42;
|
||||
--Re5_rgb: 209, 64, 62;
|
||||
--Re1_rgb: 46, 22, 23;
|
||||
--Gr5_rgb: 31, 162, 81;
|
||||
--Gr1_rgb: 17, 39, 27;
|
||||
--Or5_rgb: 214, 96, 17;
|
||||
--Or1_rgb: 48, 27, 16;
|
||||
--Ye5_rgb: 219, 135, 0;
|
||||
--Ye1_rgb: 52, 36, 16;
|
||||
--Wh0_rgb: 23, 24, 26;
|
||||
--Ga0_rgb: 13, 13, 14;
|
||||
--Ga1_rgb: 0, 0, 0;
|
||||
--Ga11_rgb: 36, 38, 40;
|
||||
--Ga12_rgb: 31, 32, 34;
|
||||
--Wh0_u_rgb: 255, 255, 255;
|
||||
--Ga10_rgb: 231, 233, 235;
|
||||
--Ga7_rgb: 162, 167, 174;
|
||||
--Ga5_rgb: 117, 122, 129;
|
||||
--Ga3_rgb: 70, 73, 77;
|
||||
--Lb6_rgb: 44, 156, 200;
|
||||
--Ye6_rgb: 225, 156, 44;
|
||||
--Ga1_s_rgb: 35, 37, 39;
|
||||
--Ga2_rgb: 47, 49, 52;
|
||||
--Ga0_s_rgb: 30, 32, 34;
|
||||
--Ba0_rgb: 0, 0, 0;
|
||||
}
|
||||
html:root {
|
||||
--brand_blue: var(--theme-color);
|
||||
|
||||
@ -0,0 +1 @@
|
||||
简化版的夜间模式,跟随 b 站官方的深色主题。
|
||||
109
registry/lib/components/style/dark-mode/integrated/index.ts
Normal file
109
registry/lib/components/style/dark-mode/integrated/index.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { defineComponentMetadata } from '@/components/component'
|
||||
import { getCookieValue } from '@/core/utils'
|
||||
|
||||
const name = 'integratedDarkMode'
|
||||
const darkModeClass = 'dark'
|
||||
const integratedDarkModeClass = 'integrated-dark'
|
||||
const darkMetaColor = '#111'
|
||||
|
||||
const isOfficialDarkModeEnabled = () => {
|
||||
return getCookieValue('theme_style') === 'dark'
|
||||
}
|
||||
|
||||
const enableDarkMode = () => {
|
||||
document.body.classList.add(darkModeClass, integratedDarkModeClass)
|
||||
|
||||
const themeColorMeta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
||||
if (!themeColorMeta) {
|
||||
document.head.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
`<meta name="theme-color" content="${darkMetaColor}">`,
|
||||
)
|
||||
} else {
|
||||
themeColorMeta.dataset.light = themeColorMeta.content
|
||||
themeColorMeta.content = darkMetaColor
|
||||
}
|
||||
|
||||
const colorSchemeMeta = dq('meta[name="color-scheme"]') as HTMLMetaElement
|
||||
if (!colorSchemeMeta) {
|
||||
document.head.insertAdjacentHTML('beforeend', `<meta name="color-scheme" content="dark">`)
|
||||
} else {
|
||||
colorSchemeMeta.content = 'dark'
|
||||
}
|
||||
}
|
||||
|
||||
const disableDarkMode = () => {
|
||||
document.body.classList.remove(darkModeClass, integratedDarkModeClass)
|
||||
|
||||
const themeColorMeta = dq('meta[name="theme-color"]') as HTMLMetaElement
|
||||
if (themeColorMeta?.dataset.light) {
|
||||
themeColorMeta.content = themeColorMeta.dataset.light
|
||||
} else {
|
||||
themeColorMeta?.remove()
|
||||
}
|
||||
|
||||
const colorSchemeMeta = dq('meta[name="color-scheme"]') as HTMLMetaElement
|
||||
if (colorSchemeMeta) {
|
||||
colorSchemeMeta.content = 'light'
|
||||
}
|
||||
}
|
||||
|
||||
const toggleDarkModeByCookie = () => {
|
||||
if (isOfficialDarkModeEnabled()) {
|
||||
enableDarkMode()
|
||||
} else {
|
||||
disableDarkMode()
|
||||
}
|
||||
}
|
||||
|
||||
const cookieChangeHandler = (e: CookieChangedEvent) => {
|
||||
if (e.changed.some(cookie => cookie.name === 'theme_style')) {
|
||||
toggleDarkModeByCookie()
|
||||
}
|
||||
}
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
name,
|
||||
displayName: '深色模式',
|
||||
entry: () => {
|
||||
cookieStore.addEventListener('change', cookieChangeHandler)
|
||||
},
|
||||
reload: () => {
|
||||
cookieStore.addEventListener('change', cookieChangeHandler)
|
||||
toggleDarkModeByCookie()
|
||||
},
|
||||
unload: () => {
|
||||
cookieStore.removeEventListener('change', cookieChangeHandler)
|
||||
document.body.classList.remove(darkModeClass, integratedDarkModeClass)
|
||||
},
|
||||
tags: [componentsTags.style, componentsTags.general],
|
||||
instantStyles: [
|
||||
{
|
||||
name,
|
||||
style: () => import('./integrated-variables.scss'),
|
||||
},
|
||||
{
|
||||
name: 'integratedDarkModePatches',
|
||||
style: () => import('./patches.scss'),
|
||||
},
|
||||
],
|
||||
plugin: {
|
||||
displayName: '深色模式 - 提前注入',
|
||||
description: {
|
||||
'zh-CN': '提前注入深色模式的 .dark class 以减少一些组件首屏仍然是白色的问题.',
|
||||
},
|
||||
async setup() {
|
||||
if (!isOfficialDarkModeEnabled()) {
|
||||
return
|
||||
}
|
||||
const { contentLoaded } = await import('@/core/life-cycle')
|
||||
const { isComponentEnabled } = await import('@/core/settings')
|
||||
contentLoaded(() => {
|
||||
if (isComponentEnabled(name)) {
|
||||
cookieStore.addEventListener('change', cookieChangeHandler)
|
||||
toggleDarkModeByCookie()
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -0,0 +1,33 @@
|
||||
// https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676
|
||||
body.integrated-dark {
|
||||
--be-color-text-title: var(--text1);
|
||||
--be-color-text-content: var(--text1);
|
||||
--be-color-text-placeholder: var(--text2);
|
||||
|
||||
--be-color-card-bg: var(--bg1_float);
|
||||
--be-color-card-border: var(--line_regular);
|
||||
|
||||
--be-color-tooltip-bg: var(--bg1_float);
|
||||
|
||||
--be-color-button-bg: var(--bg1_float);
|
||||
--be-color-button-bg-hover: var(--graph_bg_thick);
|
||||
--be-color-button-border: var(--line_regular);
|
||||
|
||||
--be-color-switch-bg: rgba(var(--graph_medium_rgb), 0.3);
|
||||
|
||||
--be-color-thumb-bg: var(--Ga4);
|
||||
--be-color-thumb-border: var(--Ga3);
|
||||
|
||||
--be-color-tag-bg: rgba(var(--graph_medium_rgb), 0.1);
|
||||
--be-color-tag-bg-hover: rgba(var(--graph_medium_rgb), 0.2);
|
||||
--be-color-tag-bg-active: rgba(var(--graph_medium_rgb), 0.3);
|
||||
|
||||
--be-color-avatar-border: var(--line_light);
|
||||
--be-color-highlight-bg-hover: rgba(var(--graph_medium_rgb), 0.1);
|
||||
|
||||
--be-color-panel-bg: var(--bg1);
|
||||
--be-color-panel-border: var(--line_light);
|
||||
|
||||
--be-color-popup-bg: var(--bg1);
|
||||
--be-color-popup-border: var(--line_light);
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
body:has(.bili-dyn-home--member) {
|
||||
background-color: #11171F;
|
||||
}
|
||||
@ -1,3 +1,24 @@
|
||||
.recommended-swipe.grid-anchor {
|
||||
display: none !important;
|
||||
$prefix: 'hideHomeCarousel-switch';
|
||||
|
||||
.#{$prefix} {
|
||||
&-full .recommended-swipe {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&-transparent .recommended-swipe {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&-picture .vui_carousel__slide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&-footerText .carousel-footer-text {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.vui_carousel__slide {
|
||||
filter: blur(var(--blur-amount, 0px));
|
||||
}
|
||||
|
||||
@ -1 +1,14 @@
|
||||
隐藏首页的轮播图区域.
|
||||
隐藏首页的轮播图区域
|
||||
|
||||
选项说明:
|
||||
|
||||
- `禁用轮播`:禁用图片轮播,可以手动切换
|
||||
- `图片模糊`:模糊轮播图片,为0时不模糊
|
||||
- `样式开关`:
|
||||
- `隐藏轮播区域占位`:完全隐藏整个轮播区域
|
||||
- `透明化轮播区域`:完全透明化整个轮播区域,同时禁止点击打开链接
|
||||
- `隐藏轮播图片`:隐藏轮播图片,同时禁止点击图片打开链接
|
||||
- `隐藏图片标题`:隐藏图片标题,同时禁止点击标题打开链接
|
||||
|
||||
> 注:样式开关可以同时启用,但是最终显示效果以作用范围大的为准
|
||||
> 例如启用 `隐藏轮播区域占位`,由于整个区域都被隐藏,不管 `隐藏轮播图片`、`隐藏图片标题` 等选项是否启用都已经看不见了
|
||||
|
||||
@ -1,9 +1,84 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { wrapSwitchOptions } from '@/components/switch-options'
|
||||
import { ComponentEntry } from '@/components/types'
|
||||
import { addComponentListener } from '@/core/settings'
|
||||
import { select, selectAll } from '@/core/spin-query'
|
||||
import { useScopedConsole } from '@/core/utils/log'
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
const logger = useScopedConsole('hideHomeCarousel')
|
||||
|
||||
// 轮播容器 mouseleave 事件拦截
|
||||
const onCarouselMouseLeaveHandler = (event: MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
const entry: ComponentEntry = async ({ metadata }) => {
|
||||
// 监听【禁用轮播】选项
|
||||
addComponentListener(
|
||||
`${metadata.name}.disableCarousel`,
|
||||
async (value: boolean) => {
|
||||
const node = (await select('.vui_carousel')) as HTMLElement
|
||||
if (!node) {
|
||||
logger.error('找不到轮播容器节点')
|
||||
return
|
||||
}
|
||||
|
||||
if (value) {
|
||||
node.addEventListener('mouseleave', onCarouselMouseLeaveHandler, true)
|
||||
// 触发事件停止轮播
|
||||
const event = new MouseEvent('mouseenter')
|
||||
node.dispatchEvent(event)
|
||||
} else {
|
||||
node.removeEventListener('mouseleave', onCarouselMouseLeaveHandler, true)
|
||||
// 触发事件恢复轮播
|
||||
const event = new MouseEvent('mouseleave')
|
||||
node.dispatchEvent(event)
|
||||
}
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
// 监听【图片模糊】选项
|
||||
addComponentListener(
|
||||
`${metadata.name}.blur`,
|
||||
async (value: number) => {
|
||||
const nodes = (await selectAll('.vui_carousel__slide')) as HTMLElement[]
|
||||
if (!nodes || nodes.length === 0) {
|
||||
logger.error('找不到轮播图片节点')
|
||||
return
|
||||
}
|
||||
|
||||
nodes.forEach(node => {
|
||||
node.style.setProperty('--blur-amount', `${value}px`)
|
||||
})
|
||||
},
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
export const component = wrapSwitchOptions({
|
||||
name: 'hideHomeCarouselOptions',
|
||||
switches: {
|
||||
full: {
|
||||
displayName: '隐藏轮播区域占位',
|
||||
defaultValue: true,
|
||||
},
|
||||
transparent: {
|
||||
displayName: '透明化轮播区域',
|
||||
defaultValue: false,
|
||||
},
|
||||
picture: {
|
||||
displayName: '隐藏轮播图片',
|
||||
defaultValue: false,
|
||||
},
|
||||
footerText: {
|
||||
displayName: '隐藏图片标题',
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
})({
|
||||
name: 'hideHomeCarousel',
|
||||
displayName: '隐藏首页轮播图',
|
||||
entry: none,
|
||||
entry,
|
||||
tags: [componentsTags.style],
|
||||
urlInclude: [/^https:\/\/www\.bilibili\.com\/$/, /^https:\/\/www\.bilibili\.com\/index\.html$/],
|
||||
instantStyles: [
|
||||
@ -12,4 +87,19 @@ export const component = defineComponentMetadata({
|
||||
style: () => import('./hide-home-carousel.scss'),
|
||||
},
|
||||
],
|
||||
options: {
|
||||
disableCarousel: {
|
||||
displayName: '禁用轮播',
|
||||
defaultValue: false,
|
||||
},
|
||||
blur: {
|
||||
displayName: '图片模糊',
|
||||
defaultValue: 0,
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -70,7 +70,7 @@ export default Vue.extend({
|
||||
padding: 6px 6px 6px 10px;
|
||||
@include v-stretch(6px);
|
||||
body.dark & {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-card-bg, #333);
|
||||
}
|
||||
.title {
|
||||
@include semi-bold();
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { useScopedConsole } from '@/core/utils/log'
|
||||
import { bilibiliApi, getJsonWithCredentials } from '@/core/ajax'
|
||||
import { select } from '@/core/spin-query'
|
||||
import { allMutations } from '@/core/observer'
|
||||
import { getUserInfo } from '@/core/user-info'
|
||||
|
||||
const displayName = '关注时间显示'
|
||||
const console = useScopedConsole(displayName)
|
||||
@ -22,20 +25,16 @@ type FollowTimeInfo = {
|
||||
const midMap: Record<number, FollowTimeInfo> = {}
|
||||
|
||||
const insertFollowTimeToCard = (mid: number, dateStr: string, label: string) => {
|
||||
const anchor = document.querySelector<HTMLAnchorElement>(
|
||||
`${SELECTORS.relationCardAnchor}[href*="/${mid}"]`,
|
||||
)
|
||||
const anchor = dq(`${SELECTORS.relationCardAnchor}[href*="/${mid}"]`)
|
||||
const card = anchor?.closest(SELECTORS.relationCardContainer)
|
||||
if (!card) {
|
||||
return
|
||||
}
|
||||
if (card.querySelector(`.${SELECTORS.relationCardTimeClass}`)) {
|
||||
if (!card || card.querySelector(`.${SELECTORS.relationCardTimeClass}`)) {
|
||||
return
|
||||
}
|
||||
|
||||
const div = document.createElement('div')
|
||||
div.className = SELECTORS.relationCardTimeClass
|
||||
div.textContent = `${label}:${dateStr}`
|
||||
div.dataset.mid = mid.toString()
|
||||
|
||||
const sign = card.querySelector(SELECTORS.relationCardSign)
|
||||
if (sign?.parentNode) {
|
||||
@ -43,57 +42,37 @@ const insertFollowTimeToCard = (mid: number, dateStr: string, label: string) =>
|
||||
}
|
||||
}
|
||||
|
||||
let fetchWrapped = false
|
||||
let pendingUpdate = false
|
||||
|
||||
const updateCards = () => {
|
||||
if (pendingUpdate) {
|
||||
return
|
||||
}
|
||||
pendingUpdate = true
|
||||
requestAnimationFrame(() => {
|
||||
pendingUpdate = false
|
||||
const mids = Array.from(
|
||||
document.querySelectorAll<HTMLAnchorElement>(SELECTORS.relationCardAnchor),
|
||||
)
|
||||
.map(el => el.href.match(/\/(\d+)/)?.[1])
|
||||
.filter(Boolean)
|
||||
.map(Number)
|
||||
|
||||
mids.forEach(mid => {
|
||||
const data = midMap[mid]
|
||||
if (data) {
|
||||
const dateStr = new Date(data.mtime * 1000).toLocaleString()
|
||||
insertFollowTimeToCard(mid, dateStr, data.label)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const waitForProfileContainer = () =>
|
||||
new Promise<Element>(resolve => {
|
||||
const check = () => document.querySelector(SELECTORS.profileFollowContainer)
|
||||
let container = check()
|
||||
if (container) {
|
||||
resolve(container)
|
||||
} else {
|
||||
const observer = new MutationObserver(() => {
|
||||
container = check()
|
||||
if (container) {
|
||||
observer.disconnect()
|
||||
resolve(container)
|
||||
const updateCards = (() => {
|
||||
let scheduled = false
|
||||
return () => {
|
||||
if (scheduled) {
|
||||
return
|
||||
}
|
||||
scheduled = true
|
||||
requestAnimationFrame(() => {
|
||||
scheduled = false
|
||||
dqa(SELECTORS.relationCardAnchor).forEach(el => {
|
||||
const match = (el as HTMLAnchorElement).href.match(/\/(\d+)/)
|
||||
if (!match) {
|
||||
return
|
||||
}
|
||||
const mid = Number(match[1])
|
||||
if (Number.isNaN(mid)) {
|
||||
return
|
||||
}
|
||||
const data = midMap[mid]
|
||||
if (data) {
|
||||
const dateStr = new Date(data.mtime * 1000).toLocaleString()
|
||||
insertFollowTimeToCard(mid, dateStr, data.label)
|
||||
}
|
||||
})
|
||||
observer.observe(document.body, { childList: true, subtree: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})()
|
||||
|
||||
const insertSubscribeTime = (followTimeStr: string) => {
|
||||
const container = document.querySelector(SELECTORS.profileFollowContainer)
|
||||
if (!container) {
|
||||
return
|
||||
}
|
||||
if (container.querySelector(`.${SELECTORS.profileTextClass}`)) {
|
||||
const container = dq(SELECTORS.profileFollowContainer)
|
||||
if (!container || container.querySelector(`.${SELECTORS.profileTextClass}`)) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -107,25 +86,22 @@ const insertSubscribeTime = (followTimeStr: string) => {
|
||||
container.appendChild(infoEl)
|
||||
}
|
||||
|
||||
const entry = async () => {
|
||||
try {
|
||||
const { addImportantStyle } = await import('@/core/style')
|
||||
const { default: style } = await import('./subscribe-time.scss')
|
||||
addImportantStyle(style, 'subscribe-time-style')
|
||||
} catch (e) {
|
||||
console.error('样式加载失败:', e)
|
||||
}
|
||||
if (!(unsafeWindow as any).subscribeTimeHooked) {
|
||||
;(unsafeWindow as any).subscribeTimeHooked = true
|
||||
const originalFetch = unsafeWindow.fetch
|
||||
unsafeWindow.fetch = new Proxy(originalFetch, {
|
||||
apply(target, thisArg, args) {
|
||||
const url = typeof args[0] === 'string' ? args[0] : args[0].url
|
||||
const urlObj = new URL(url, location.origin)
|
||||
|
||||
new MutationObserver(updateCards).observe(document.body, { childList: true, subtree: true })
|
||||
|
||||
if (!fetchWrapped) {
|
||||
fetchWrapped = true
|
||||
const originalFetch = unsafeWindow.fetch
|
||||
unsafeWindow.fetch = new Proxy(originalFetch, {
|
||||
apply(target, thisArg, args) {
|
||||
const url = typeof args[0] === 'string' ? args[0] : args[0].url
|
||||
if (url.includes('/x/relation/fans') || url.includes('/x/relation/followings')) {
|
||||
return target.apply(thisArg, args).then(res => {
|
||||
if (
|
||||
urlObj.hostname === 'api.bilibili.com' &&
|
||||
(urlObj.pathname.includes('/x/relation/fans') ||
|
||||
urlObj.pathname.includes('/x/relation/followings'))
|
||||
) {
|
||||
return target
|
||||
.apply(thisArg, args)
|
||||
.then(res => {
|
||||
res
|
||||
.clone()
|
||||
.json()
|
||||
@ -137,54 +113,63 @@ const entry = async () => {
|
||||
}
|
||||
list.forEach(user => {
|
||||
if (typeof user.mid === 'number' && typeof user.mtime === 'number') {
|
||||
const label = url.includes('/x/relation/fans')
|
||||
? 'Ta 关注你的时间'
|
||||
: '你关注 Ta 的时间'
|
||||
const label = url.includes('/fans') ? 'Ta 关注你的时间' : '你关注 Ta 的时间'
|
||||
midMap[user.mid] = { mtime: user.mtime, label }
|
||||
insertFollowTimeToCard(
|
||||
user.mid,
|
||||
new Date(user.mtime * 1000).toLocaleString(),
|
||||
label,
|
||||
)
|
||||
const dateStr = new Date(user.mtime * 1000).toLocaleString()
|
||||
insertFollowTimeToCard(user.mid, dateStr, label)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(err => console.warn('JSON 解析失败:', err))
|
||||
.catch(err => {
|
||||
console.warn('JSON 解析失败:', err)
|
||||
})
|
||||
return res
|
||||
})
|
||||
}
|
||||
return target.apply(thisArg, args)
|
||||
},
|
||||
})
|
||||
.catch(err => {
|
||||
console.warn('fetch 请求失败:', err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
return target.apply(thisArg, args)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const entry = async () => {
|
||||
try {
|
||||
const { addImportantStyle } = await import('@/core/style')
|
||||
const { default: style } = await import('./subscribe-time.scss')
|
||||
addImportantStyle(style, 'subscribe-time-style')
|
||||
} catch (e) {
|
||||
console.error('样式加载失败:', e)
|
||||
}
|
||||
|
||||
allMutations(updateCards)
|
||||
|
||||
const userMid = (await getUserInfo()).mid
|
||||
const match = location.href.match(/space\.bilibili\.com\/(\d+)/)
|
||||
if (!match) {
|
||||
console.warn('无法提取 mid')
|
||||
return
|
||||
}
|
||||
|
||||
const mid = Number(match[1])
|
||||
if (mid === userMid) {
|
||||
console.log('当前为本人空间,跳过关注时间显示')
|
||||
return
|
||||
}
|
||||
|
||||
const info = await bilibiliApi(
|
||||
getJsonWithCredentials(`https://api.bilibili.com/x/web-interface/relation?mid=${mid}`),
|
||||
)
|
||||
if (!info?.relation) {
|
||||
console.warn('未获取到 relation 信息')
|
||||
return
|
||||
}
|
||||
if (!info.relation.mtime) {
|
||||
console.log('当前未关注或关注时间无效')
|
||||
|
||||
const mtime = info?.relation?.mtime
|
||||
if (!mtime) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await waitForProfileContainer()
|
||||
} catch (e) {
|
||||
console.warn('等待关注容器超时,跳过插入关注时间')
|
||||
return
|
||||
}
|
||||
|
||||
insertSubscribeTime(new Date(info.relation.mtime * 1000).toLocaleString())
|
||||
await select(SELECTORS.profileFollowContainer)
|
||||
insertSubscribeTime(new Date(mtime * 1000).toLocaleString())
|
||||
}
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
@ -200,5 +185,7 @@ export const component = defineComponentMetadata({
|
||||
/https:\/\/space\.bilibili\.com\/\d+/,
|
||||
],
|
||||
entry,
|
||||
description: { 'zh-CN': '在粉丝/关注列表及用户主页显示关注的具体时间。' },
|
||||
description: {
|
||||
'zh-CN': '在粉丝/关注列表及用户主页显示关注的具体时间。',
|
||||
},
|
||||
})
|
||||
|
||||
@ -115,7 +115,10 @@ export default Vue.extend({
|
||||
user-select: text;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 0 0 1px #8884;
|
||||
@include default-background-color();
|
||||
background-color: #fff;
|
||||
body.dark & {
|
||||
background-color: var(--be-color-card-bg, #333);
|
||||
}
|
||||
&-item {
|
||||
font-size: 14px;
|
||||
@include h-center(6px);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.10.2",
|
||||
"version": "2.10.3",
|
||||
"author": "Grant Howard, Coulomb-G",
|
||||
"copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)",
|
||||
"license": "MIT",
|
||||
|
||||
@ -341,8 +341,8 @@ export default Vue.extend({
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
background-color: #222;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
background-color: var(--be-color-panel-bg, #222);
|
||||
}
|
||||
.suggest-highlight {
|
||||
color: var(--theme-color);
|
||||
|
||||
@ -133,7 +133,7 @@ export default Vue.extend({
|
||||
min-width: 372px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
@include card();
|
||||
@include popup();
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
@ -197,7 +197,7 @@ export default Vue.extend({
|
||||
border-right: 1px solid #8882;
|
||||
|
||||
body.dark & {
|
||||
background-color: #222;
|
||||
background-color: var(--be-color-panel-bg, #222);
|
||||
}
|
||||
}
|
||||
.icon-list:hover ~ .component-tags,
|
||||
|
||||
@ -163,14 +163,14 @@ export default {
|
||||
transform: translateX(calc(60% * var(--direction))) scale(1.1);
|
||||
background-color: #fff;
|
||||
body.dark & {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-button-bg, #333);
|
||||
}
|
||||
.be-icon {
|
||||
color: #222;
|
||||
fill: #222;
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
fill: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
fill: var(--be-color-text-title, #eee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,8 +278,8 @@ export default {
|
||||
height: var(--panel-height);
|
||||
transition: opacity 0.2s 0.2s ease-out;
|
||||
body.dark & {
|
||||
--settings-panel-background: #222;
|
||||
color: #eee;
|
||||
--settings-panel-background: var(--be-color-panel-bg, #222);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
// border-color: #333;
|
||||
}
|
||||
.settings-panel-header {
|
||||
@ -386,7 +386,7 @@ export default {
|
||||
}
|
||||
}
|
||||
.component-detail-panel {
|
||||
@include card();
|
||||
@include popup();
|
||||
@include v-stretch();
|
||||
top: 50%;
|
||||
left: calc(100% - 12px);
|
||||
|
||||
36
src/cookie-store.d.ts
vendored
Normal file
36
src/cookie-store.d.ts
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
interface Cookie {
|
||||
domain: string
|
||||
expires: number
|
||||
name: string
|
||||
partitioned: boolean
|
||||
path: string
|
||||
sameSite: 'Strict' | 'Lax' | 'None'
|
||||
secure: boolean
|
||||
value: string
|
||||
}
|
||||
|
||||
interface CookieChangedEvent extends Event {
|
||||
changed: Readonly<Array<Cookie>>
|
||||
deleted: Readonly<Array<Cookie>>
|
||||
}
|
||||
|
||||
interface CookieStore {
|
||||
get(name: string): Promise<Cookie | null>
|
||||
get(options: { name: string; url?: string }): Promise<Cookie | null>
|
||||
|
||||
getAll(): Promise<Cookie[]>
|
||||
getAll(name: string): Promise<Cookie[]>
|
||||
getAll(options: { name?: string; url?: string }): Promise<Cookie[]>
|
||||
|
||||
set(name: string, value: string): Promise<void>
|
||||
set(options: Partial<Cookie> & { name: string; value: string }): Promise<void>
|
||||
|
||||
delete(name: string): Promise<void>
|
||||
delete(options: { name: string; url?: string }): Promise<void>
|
||||
|
||||
addEventListener(eventName: 'change', handler: (event: CookieChangedEvent) => void): void
|
||||
removeEventListener(eventName: 'change', handler: (event: CookieChangedEvent) => void): void
|
||||
onchange: null | ((event: CookieChangedEvent) => void)
|
||||
}
|
||||
|
||||
declare const cookieStore: CookieStore
|
||||
@ -29,66 +29,60 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { VIcon, ProgressRing } from '@/ui'
|
||||
import type { Toast } from '.'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
VIcon,
|
||||
ProgressRing,
|
||||
},
|
||||
props: {
|
||||
card: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
progressMax: 0,
|
||||
remainingTime: 0,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.readDuration()
|
||||
},
|
||||
methods: {
|
||||
durationTick() {
|
||||
const { closeTime } = this.card as Toast
|
||||
if (!closeTime) {
|
||||
return
|
||||
}
|
||||
this.remainingTime = closeTime - Number(new Date())
|
||||
if (this.remainingTime > 0) {
|
||||
requestAnimationFrame(() => this.durationTick())
|
||||
}
|
||||
},
|
||||
readDuration() {
|
||||
const { duration, closeTime } = this.card as Toast
|
||||
if (duration) {
|
||||
this.progressMax = closeTime - Number(new Date())
|
||||
this.remainingTime = this.progressMax
|
||||
requestAnimationFrame(() => this.durationTick())
|
||||
}
|
||||
},
|
||||
stopTimer() {
|
||||
;(this.card as Toast).clearDuration()
|
||||
this.progressMax = 0
|
||||
this.remainingTime = 0
|
||||
},
|
||||
startTimer() {
|
||||
;(this.card as Toast).setDuration()
|
||||
this.readDuration()
|
||||
},
|
||||
},
|
||||
interface Props {
|
||||
card: Toast
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const progressMax = ref(0)
|
||||
const remainingTime = ref(0)
|
||||
|
||||
const durationTick = () => {
|
||||
const { closeTime } = props.card
|
||||
if (!closeTime) {
|
||||
return
|
||||
}
|
||||
remainingTime.value = closeTime - Number(new Date())
|
||||
if (remainingTime.value > 0) {
|
||||
requestAnimationFrame(() => durationTick())
|
||||
}
|
||||
}
|
||||
|
||||
const readDuration = () => {
|
||||
const { duration, closeTime } = props.card
|
||||
if (duration) {
|
||||
progressMax.value = closeTime - Number(new Date())
|
||||
remainingTime.value = progressMax.value
|
||||
requestAnimationFrame(() => durationTick())
|
||||
}
|
||||
}
|
||||
|
||||
const stopTimer = () => {
|
||||
props.card.clearDuration()
|
||||
progressMax.value = 0
|
||||
remainingTime.value = 0
|
||||
}
|
||||
|
||||
const startTimer = () => {
|
||||
props.card.setDuration()
|
||||
readDuration()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
readDuration()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
.toast-card {
|
||||
background: #fff;
|
||||
background: var(--be-color-card-bg, #fff);
|
||||
min-width: var(--card-min-width);
|
||||
max-width: 60vw;
|
||||
min-height: 87px;
|
||||
@ -119,14 +113,11 @@ export default Vue.extend({
|
||||
}
|
||||
&-title {
|
||||
font-size: 18px;
|
||||
color: #444;
|
||||
color: var(--be-color-text-title, #444);
|
||||
opacity: 0.5;
|
||||
margin: 12px;
|
||||
@include semi-bold();
|
||||
flex: 1 1 auto;
|
||||
body.dark & {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&-close {
|
||||
height: 24px;
|
||||
@ -166,7 +157,7 @@ export default Vue.extend({
|
||||
}
|
||||
}
|
||||
&-message {
|
||||
color: #000;
|
||||
color: var(--be-color-text-content, #000);
|
||||
font-size: 14px;
|
||||
margin: 0 16px 12px 12px;
|
||||
white-space: pre-wrap;
|
||||
@ -196,19 +187,19 @@ export default Vue.extend({
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin: 2px;
|
||||
background-color: #8882;
|
||||
background-color: var(--be-color-tag-bg, #8882);
|
||||
color: var(--be-color-text-content, #000);
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
transition: all 0.2s ease-out;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.link {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #8883;
|
||||
background-color: var(--be-color-tag-bg-hover, #8883);
|
||||
}
|
||||
&:active {
|
||||
background-color: #8884;
|
||||
background-color: var(--be-color-tag-bg-active, #8884);
|
||||
}
|
||||
}
|
||||
.download-link,
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
.tippy-box {
|
||||
.tippy-box.tippy-box {
|
||||
font-size: inherit;
|
||||
filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.2));
|
||||
background-color: var(--be-color-tooltip-bg, #333);
|
||||
}
|
||||
.tippy-arrow.tippy-arrow {
|
||||
color: var(--be-color-tooltip-bg, #333);
|
||||
}
|
||||
|
||||
@ -322,7 +322,7 @@ export default Vue.extend({
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
.selected-color {
|
||||
cursor: pointer;
|
||||
|
||||
@ -71,7 +71,7 @@ export default Vue.extend({
|
||||
|
||||
.bar {
|
||||
position: relative;
|
||||
background-color: #8884;
|
||||
background-color: var(--be-color-switch-bg, #8884);
|
||||
// box-shadow: 0 1px 4px 0 #0004 inset;
|
||||
@include round-bar(12);
|
||||
.thumb {
|
||||
@ -86,8 +86,8 @@ export default Vue.extend({
|
||||
border: 1px solid #ddd;
|
||||
// box-shadow: 0 1px 8px 0px #0004;
|
||||
body.dark & {
|
||||
border-color: #555;
|
||||
background-color: #666;
|
||||
border-color: var(--be-color-thumb-border, #555);
|
||||
background-color: var(--be-color-thumb-bg, #666);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,14 +48,14 @@ export default Vue.extend({
|
||||
color: black;
|
||||
font-size: inherit;
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
color: var(--be-color-text-content, #eee);
|
||||
}
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
color: #888;
|
||||
color: var(--be-color-text-placeholder, #888);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,14 +56,14 @@ export default Vue.extend({
|
||||
width: 0;
|
||||
font-size: inherit;
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
color: var(--be-color-text-content, #eee);
|
||||
}
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
color: #888;
|
||||
color: var(--be-color-text-placeholder, #888);
|
||||
}
|
||||
}
|
||||
&.linear {
|
||||
|
||||
@ -59,7 +59,7 @@ export default Vue.extend({
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
&.round {
|
||||
border-radius: calc(1em + 8px);
|
||||
@ -93,7 +93,7 @@ export default Vue.extend({
|
||||
transition: box-shadow 0.2s ease-out;
|
||||
}
|
||||
body.dark &.light {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-button-bg, #333);
|
||||
// box-shadow: 0 0 0 1px transparent;
|
||||
}
|
||||
&:not(.disabled) {
|
||||
@ -135,12 +135,12 @@ export default Vue.extend({
|
||||
}
|
||||
body.dark &.light {
|
||||
&:hover {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-button-bg, #333);
|
||||
box-shadow: 0 0 0 1px var(--theme-color);
|
||||
}
|
||||
&:active,
|
||||
&:focus-within {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-button-bg, #333);
|
||||
box-shadow: 0 0 0 1px var(--theme-color), 0 0 0 3px var(--theme-color-20);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ export default Vue.extend({
|
||||
outline: none !important;
|
||||
}
|
||||
body.dark & {
|
||||
background-color: #333;
|
||||
background-color: var(--be-color-button-bg, #333);
|
||||
}
|
||||
&:not(.disabled) {
|
||||
&:hover {
|
||||
|
||||
@ -84,14 +84,14 @@
|
||||
box-sizing: border-box;
|
||||
@include shadow();
|
||||
body.dark & {
|
||||
background-color: #282828;
|
||||
color: #eee;
|
||||
background-color: var(--be-color-card-bg, #282828);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
}
|
||||
}
|
||||
@mixin popup($radius: 8px) {
|
||||
@include card($radius);
|
||||
body.dark & {
|
||||
background-color: #222;
|
||||
background-color: var(--be-color-popup-bg, #222);
|
||||
}
|
||||
}
|
||||
@mixin border-card($radius: 8px) {
|
||||
@ -100,9 +100,9 @@
|
||||
border-radius: $radius;
|
||||
border: 1px solid #e8e8e8;
|
||||
body.dark & {
|
||||
background-color: #222;
|
||||
color: #eee;
|
||||
border-color: #333;
|
||||
background-color: var(--be-color-card-bg, #222);
|
||||
color: var(--be-color-text-title, #eee);
|
||||
border-color: var(--be-color-card-border, #333);
|
||||
}
|
||||
}
|
||||
// @mixin popup($radius: 8px) {
|
||||
@ -123,15 +123,15 @@
|
||||
fill: black;
|
||||
stroke: black;
|
||||
body.dark & {
|
||||
color: #eee;
|
||||
fill: #eee;
|
||||
stroke: #eee;
|
||||
color: var(--be-color-text-title, #eee);
|
||||
fill: var(--be-color-text-title, #eee);
|
||||
stroke: var(--be-color-text-title, #eee);
|
||||
}
|
||||
}
|
||||
@mixin semi-bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
@mixin default-background-color($dark-color: #333) {
|
||||
@mixin default-background-color($dark-color: var(--be-color-panel-bg, #333)) {
|
||||
background-color: #fff;
|
||||
body.dark & {
|
||||
background-color: $dark-color;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user