mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Merge branch 'preview-fixes'
This commit is contained in:
commit
95fd680f29
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -51,6 +51,7 @@
|
||||
"Fullscreen",
|
||||
"githubusercontent",
|
||||
"Greasemonkey",
|
||||
"guochuang",
|
||||
"haruna",
|
||||
"hdslb",
|
||||
"HEVC",
|
||||
|
||||
54
CHANGELOG.md
54
CHANGELOG.md
@ -1,6 +1,60 @@
|
||||
<!-- spell-checker: disable -->
|
||||
# 更新日志
|
||||
|
||||
## v2.10.1-preview
|
||||
`2025-04-09`
|
||||
|
||||
包含 [v2.10.1](https://github.com/the1812/Bilibili-Evolved/releases/tag/v2.10.1) 的所有更新内容.
|
||||
|
||||
- 新增组件 `一键点亮直播间粉丝勋章`. (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)
|
||||
|
||||
## v2.10.1
|
||||
`2025-04-09`
|
||||
|
||||
<details>
|
||||
<summary>正式版用户将获得 v2.9.6-preview ~ v2.10.0-preview 的所有改动, 点击展开查看</summary>
|
||||
|
||||
- 新增插件 `自定义顶栏 - 版权内容`. (#5045)
|
||||
> 为自定义顶栏扩充版权内容相关的快速入口, 包括国创 / 电影 / 电视剧 /综艺 / 纪录片
|
||||
|
||||
- 视频截图在还有截图未处理 (保存 / 丢弃) 时, 离开页面增加二次确认. (#5066)
|
||||
- `插件 - 下载视频 - WASM 混流输出` 在超过 4GB 时支持抛出错误提示. (PR #5102 by [WakelessSloth56](https://github.com/WakelessSloth56))
|
||||
- `自定义顶栏` 的透明填充在同时开启了全局固定时, 支持下拉后过渡到不透明状态. (#4996)
|
||||
- `自定义顶栏` 的弹窗增加了 0.2s 的触发延迟, 防止鼠标快速经过时误触. (#4949)
|
||||
- 废弃 `双击全屏` 组件, 本体也不再会屏蔽双击全屏. (#5095)
|
||||
|
||||
</details>
|
||||
|
||||
✨新增
|
||||
- 新增组件 `禁用双击全屏`. (#5095)
|
||||
> ⚠ 请注意 `双击全屏` 组件已废弃, 本体也不再会屏蔽双击全屏, 更新后可以直接卸载 `双击全屏` 组件
|
||||
|
||||
- `快捷键扩展` 的使用说明增加关于屏蔽 b 站自带快捷键的指南. (#5168)
|
||||
- `动态过滤器` 增加 `课程`, `直播`, `合集` 类型. (#5135)
|
||||
> 这些类型的支持是根据 b 站代码里的枚举加的, 我的动态里没有这些类型无法测试, 如果还有相关问题请继续在 #5135 中反馈
|
||||
|
||||
🐛修复
|
||||
- 修复 `快捷键扩展` 在聚焦元素相关的动作中出现失效的情况. (#5150, #5153, #5174)
|
||||
- 修复 `启用快速收藏` 在存在和默认收藏夹同名的收藏夹时, 收藏到了错误的收藏夹. (#5151)
|
||||
- 修复 `图片批量导出` 在 Firefox 中导出动态图片时出现重复图片. (#5166)
|
||||
- 修复 `夜间模式` 导致登录时二维码扫码困难. (#5163, PR #5173 by [Pencil](https://github.com/pencilqaq))
|
||||
- 修复 `删除广告` 在搜索页出现的空位. (#5032)
|
||||
|
||||
|
||||
## v2.10.0-preview
|
||||
`2025-02-25`
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
**注意事项**
|
||||
- **⚠ 使用正式版 (GitHub 源) 和预览版须翻墙.**
|
||||
- 默认不预装任何组件, 需要在按[设置](#设置)中的说明添加感兴趣的功能; 默认会屏蔽双击全屏, 如有需要可以安装 `双击全屏` 组件来恢复.
|
||||
- 默认不预装任何组件, 需要在按[设置](#设置)中的说明添加感兴趣的功能.
|
||||
- 这个是一个综合性的脚本, 如果只是想下载视频建议去 [GreasyFork](https://greasyfork.org/zh-CN/scripts/by-site/bilibili.com) 找个更专业的.
|
||||
- 对性能有较大影响, 详见[配置要求](#配置).
|
||||
- 默认不对未登录的状态做适配.
|
||||
|
||||
@ -475,7 +475,7 @@
|
||||
"type": "component",
|
||||
"name": "doubleClickControl",
|
||||
"displayName": "启用双击控制",
|
||||
"description": "将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停. 请注意不能和 `双击全屏` 一同使用.",
|
||||
"description": "将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停.\r\n",
|
||||
"fullRelativePath": "../../registry/dist/components/touch/double-click-control.js",
|
||||
"fullAbsolutePath": "registry/dist/components/touch/double-click-control.js"
|
||||
},
|
||||
@ -815,6 +815,14 @@
|
||||
"fullRelativePath": "../../registry/dist/components/video/player/default-mode.js",
|
||||
"fullAbsolutePath": "registry/dist/components/video/player/default-mode.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "disableDoubleClickFullscreen",
|
||||
"displayName": "禁用双击全屏",
|
||||
"description": "禁用播放器的双击全屏功能.\r\n",
|
||||
"fullRelativePath": "../../registry/dist/components/video/player/disable-double-click-fullscreen.js",
|
||||
"fullAbsolutePath": "registry/dist/components/video/player/disable-double-click-fullscreen.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "disableScrollVolume",
|
||||
@ -823,14 +831,6 @@
|
||||
"fullRelativePath": "../../registry/dist/components/video/player/disable-scroll-volume.js",
|
||||
"fullAbsolutePath": "registry/dist/components/video/player/disable-scroll-volume.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "doubleClickFullscreen",
|
||||
"displayName": "双击全屏",
|
||||
"description": "为视频播放器启用双击全屏功能, 请注意不能和 `启用双击控制` 一同使用.",
|
||||
"fullRelativePath": "../../registry/dist/components/video/player/double-click-fullscreen.js",
|
||||
"fullAbsolutePath": "registry/dist/components/video/player/double-click-fullscreen.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "extendVideoSpeed",
|
||||
@ -1056,6 +1056,14 @@
|
||||
"fullRelativePath": "../../registry/dist/plugins/style/custom-navbar-dark-mode.js",
|
||||
"fullAbsolutePath": "registry/dist/plugins/style/custom-navbar-dark-mode.js"
|
||||
},
|
||||
{
|
||||
"type": "plugin",
|
||||
"name": "customNavbar.items.pgc",
|
||||
"displayName": "自定义顶栏 - 版权内容",
|
||||
"description": "为自定义顶栏扩充版权内容相关的快速入口, 包括国创 / 电影 / 电视剧 /综艺 / 纪录片",
|
||||
"fullRelativePath": "../../registry/dist/plugins/style/custom-navbar-pgc.js",
|
||||
"fullAbsolutePath": "registry/dist/plugins/style/custom-navbar-pgc.js"
|
||||
},
|
||||
{
|
||||
"type": "plugin",
|
||||
"name": "keymap.actions.darkMode",
|
||||
|
||||
@ -624,7 +624,7 @@ by [@RieN7](https://github.com/rien7),[@ZiuChen](https://github.com/ZiuChen),[@L
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/touch/double-click-control.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/touch/double-click-control.js)
|
||||
|
||||
将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停. 请注意不能和 `双击全屏` 一同使用.
|
||||
将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停.
|
||||
|
||||
### [迷你播放器触摸拖动](../../registry/dist/components/touch/mini-player.js)
|
||||
`touchMiniPlayer`
|
||||
@ -1124,6 +1124,15 @@ by [@WakelessSloth56](https://github.com/WakelessSloth56),[@LainIO24](https://gi
|
||||
|
||||
控制是否使用默认播放器模式, 可以为`常规`, `宽屏`, `网页全屏`或`全屏`. 注意: 不能和其他影响定位的功能一同使用, 例如播放器定位. (相关讨论: [#483](https://github.com/the1812/Bilibili-Evolved/issues/483))
|
||||
|
||||
### [禁用双击全屏](../../registry/dist/components/video/player/disable-double-click-fullscreen.js)
|
||||
`disableDoubleClickFullscreen`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/video/player/disable-double-click-fullscreen.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/video/player/disable-double-click-fullscreen.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/player/disable-double-click-fullscreen.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/player/disable-double-click-fullscreen.js)
|
||||
|
||||
禁用播放器的双击全屏功能.
|
||||
|
||||
### [禁止滚轮调音量](../../registry/dist/components/video/player/disable-scroll-volume.js)
|
||||
`disableScrollVolume`
|
||||
|
||||
@ -1133,15 +1142,6 @@ by [@WakelessSloth56](https://github.com/WakelessSloth56),[@LainIO24](https://gi
|
||||
|
||||
在网页全屏 / 全屏模式下, 禁止鼠标滚轮控制播放器的音量. 请注意不能和 `反转滚轮调音量` 一同使用.
|
||||
|
||||
### [双击全屏](../../registry/dist/components/video/player/double-click-fullscreen.js)
|
||||
`doubleClickFullscreen`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/video/player/double-click-fullscreen.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/video/player/double-click-fullscreen.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/player/double-click-fullscreen.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/player/double-click-fullscreen.js)
|
||||
|
||||
为视频播放器启用双击全屏功能, 请注意不能和 `启用双击控制` 一同使用.
|
||||
|
||||
### [扩展倍速](../../registry/dist/components/video/player/extend-speed.js)
|
||||
`extendVideoSpeed`
|
||||
|
||||
@ -1472,6 +1472,15 @@ by FoundTheWOUT
|
||||
|
||||
为自定义顶栏添加一个夜间模式开关, 方便快速切换夜间模式.
|
||||
|
||||
### [自定义顶栏 - 版权内容](../../registry/dist/plugins/style/custom-navbar-pgc.js)
|
||||
`customNavbar.items.pgc`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/plugins/style/custom-navbar-pgc.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/plugins/style/custom-navbar-pgc.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/plugins/style/custom-navbar-pgc.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/plugins/style/custom-navbar-pgc.js)
|
||||
|
||||
为自定义顶栏扩充版权内容相关的快速入口, 包括国创 / 电影 / 电视剧 /综艺 / 纪录片
|
||||
|
||||
### [快捷键扩展 - 夜间模式](../../registry/dist/plugins/utils/keymap-dark-mode.js)
|
||||
`keymap.actions.darkMode`
|
||||
|
||||
|
||||
@ -146,7 +146,7 @@ export default Vue.extend({
|
||||
}
|
||||
this.allTypes = Object.entries(feedsCardTypes)
|
||||
.concat(Object.entries(specialTypes))
|
||||
.filter(([, type]) => type.id <= 2048)
|
||||
.filter(([, type]) => type.id <= 2048 && type.id > 0)
|
||||
.map(([name, type]) => [name, lodash.clone(type)])
|
||||
cardsManager = await forEachFeedsCard({
|
||||
added: card => {
|
||||
|
||||
@ -74,6 +74,7 @@ export default Vue.extend({
|
||||
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
@import './scroll-animation';
|
||||
|
||||
.van-message-box {
|
||||
z-index: 10002 !important;
|
||||
@ -121,7 +122,6 @@ body.fixed-navbar {
|
||||
|
||||
.custom-navbar *,
|
||||
.custom-navbar {
|
||||
transition: all 0.2s ease-out;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
@ -170,12 +170,28 @@ export default Vue.extend({
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
|
||||
@keyframes navbar-popup-in {
|
||||
to {
|
||||
pointer-events: initial;
|
||||
}
|
||||
}
|
||||
// @keyframes navbar-popup-out {
|
||||
// from {
|
||||
// pointer-events: none;
|
||||
// }
|
||||
// to {
|
||||
// pointer-events: none;
|
||||
// opacity: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
.custom-navbar-item {
|
||||
color: inherit;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: 0.2s background-color ease-out;
|
||||
|
||||
.active-bar {
|
||||
position: absolute;
|
||||
@ -241,7 +257,7 @@ export default Vue.extend({
|
||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid #8882;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease-out 0.2s;
|
||||
transition: opacity 0.2s ease-out 0.2s;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
@ -270,14 +286,17 @@ export default Vue.extend({
|
||||
background-color: transparent !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
> * {
|
||||
@include default-transition();
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.disabled) .popup-container {
|
||||
position: absolute;
|
||||
top: calc(100% - 8px);
|
||||
left: 50%;
|
||||
transition: all 0.2s ease-out 0.2s;
|
||||
pointer-events: none;
|
||||
transition: all 0.2s ease-out 0.2s;
|
||||
}
|
||||
|
||||
&:not(.disabled):hover,
|
||||
@ -285,8 +304,7 @@ export default Vue.extend({
|
||||
.popup-container {
|
||||
top: 100%;
|
||||
> .popup {
|
||||
// transform: translateY(0) translateX(-50%);
|
||||
pointer-events: initial;
|
||||
animation: navbar-popup-in 0.2s ease-out 0.2s both;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,183 @@
|
||||
@property --navbar-foreground {
|
||||
syntax: '<color>';
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
@property --navbar-background {
|
||||
syntax: '<color>';
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
@property --foreground-color-d {
|
||||
syntax: '<color>';
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
@property --theme-color {
|
||||
syntax: '<color>';
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
@property --theme-color-60 {
|
||||
syntax: '<color>';
|
||||
inherits: true;
|
||||
initial-value: transparent;
|
||||
}
|
||||
|
||||
@keyframes transparent-to-light {
|
||||
to {
|
||||
--navbar-foreground: #555;
|
||||
--navbar-background: white;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-light-blur {
|
||||
to {
|
||||
--navbar-foreground: #555;
|
||||
--navbar-background: #fffc;
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #222;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark-blur {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #2228;
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-theme {
|
||||
to {
|
||||
--navbar-foreground: var(--foreground-color-d);
|
||||
--navbar-background: var(--theme-color);
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-theme-blur {
|
||||
to {
|
||||
--navbar-foreground: var(--foreground-color-d);
|
||||
--navbar-background: var(--theme-color-60);
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-light-shadow {
|
||||
to {
|
||||
--navbar-foreground: #555;
|
||||
--navbar-background: white;
|
||||
box-shadow: #0002 0 1px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-light-blur-shadow {
|
||||
to {
|
||||
--navbar-foreground: #555;
|
||||
--navbar-background: #fffc;
|
||||
backdrop-filter: blur(24px);
|
||||
box-shadow: #0002 0 1px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark-shadow {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #222;
|
||||
box-shadow: #0004 0px 2px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-dark-blur-shadow {
|
||||
to {
|
||||
--navbar-foreground: #eee;
|
||||
--navbar-background: #2228;
|
||||
backdrop-filter: blur(24px);
|
||||
box-shadow: #0004 0px 2px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-theme-shadow {
|
||||
to {
|
||||
--navbar-foreground: var(--foreground-color-d);
|
||||
--navbar-background: var(--theme-color);
|
||||
box-shadow: #0002 0 1px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-to-theme-blur-shadow {
|
||||
to {
|
||||
--navbar-foreground: var(--foreground-color-d);
|
||||
--navbar-background: var(--theme-color-60);
|
||||
backdrop-filter: blur(24px);
|
||||
box-shadow: #0002 0 1px 10px 1px;
|
||||
}
|
||||
}
|
||||
@keyframes transparent-mask {
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes launch-bar-colors {
|
||||
to {
|
||||
background-color: #8883;
|
||||
}
|
||||
}
|
||||
@keyframes launch-bar-colors-fill {
|
||||
to {
|
||||
background-color: #0002;
|
||||
}
|
||||
}
|
||||
|
||||
@supports (animation-timeline: scroll()) {
|
||||
.custom-navbar.transparent {
|
||||
--animation-range: clamp(116px, 7vw, 180px) clamp(155px, 9.375vw, 240px);
|
||||
&::before {
|
||||
animation: transparent-mask linear both;
|
||||
animation-timeline: scroll();
|
||||
animation-range: var(--animation-range);
|
||||
}
|
||||
body.fixed-navbar & {
|
||||
animation: transparent-to-light linear both;
|
||||
animation-timeline: scroll();
|
||||
animation-range: var(--animation-range);
|
||||
.launch-bar {
|
||||
animation: launch-bar-colors linear both;
|
||||
animation-timeline: scroll();
|
||||
animation-range: var(--animation-range);
|
||||
}
|
||||
&.shadow {
|
||||
animation-name: transparent-to-light-shadow;
|
||||
}
|
||||
&.blur:not(.fill) {
|
||||
animation-name: transparent-to-light-blur;
|
||||
&.shadow {
|
||||
animation-name: transparent-to-light-blur-shadow;
|
||||
}
|
||||
}
|
||||
&.fill {
|
||||
animation-name: transparent-to-theme;
|
||||
|
||||
.launch-bar {
|
||||
animation-name: launch-bar-colors-fill;
|
||||
}
|
||||
&.shadow {
|
||||
animation-name: transparent-to-theme-shadow;
|
||||
}
|
||||
&.blur {
|
||||
animation-name: transparent-to-theme-blur;
|
||||
&.shadow {
|
||||
animation-name: transparent-to-theme-blur-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
body.fixed-navbar.dark &:not(.fill) {
|
||||
animation-name: transparent-to-dark;
|
||||
&.shadow {
|
||||
animation-name: transparent-to-dark-shadow;
|
||||
}
|
||||
&.blur {
|
||||
animation-name: transparent-to-dark-blur;
|
||||
&.shadow {
|
||||
animation-name: transparent-to-dark-blur-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,6 +102,7 @@ export default Vue.extend({
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
transition: 0.2s background-color ease-out;
|
||||
&.loading {
|
||||
font-size: 10pt;
|
||||
cursor: initial;
|
||||
|
||||
@ -59,10 +59,11 @@ export default Vue.extend({
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: 0.2s all ease-out 0.2s;
|
||||
opacity: 1;
|
||||
z-index: 100;
|
||||
.custom-navbar-item:hover & {
|
||||
transform: scale(2) translateY(10px);
|
||||
z-index: 100;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.user-face {
|
||||
|
||||
@ -6,3 +6,28 @@
|
||||
@include background-color();
|
||||
}
|
||||
}
|
||||
|
||||
.login-scan__qrcode {
|
||||
@include background-color('f');
|
||||
.qrcode__tip {
|
||||
@include background-color('3');
|
||||
img {
|
||||
@include background-color();
|
||||
}
|
||||
span {
|
||||
@include color('a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scan-tips-icon{
|
||||
@include background-color('2');
|
||||
}
|
||||
|
||||
.btn_other {
|
||||
@include background-color('3');
|
||||
@include border-color('4');
|
||||
@include color('f');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,18 @@
|
||||
.search-panel {
|
||||
|
||||
> .trending {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:not(:has(.history)) {
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
#nav-searchform.is-focus {
|
||||
/* 搜索框 focusing 且有关键字列表 or 历史记录列表时不显示低边框*/
|
||||
&:not(:has(+ .search-panel > .suggestions), :has(+ .search-panel > .history)) {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,13 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { allMutations } from '@/core/observer'
|
||||
import { select } from '@/core/spin-query'
|
||||
|
||||
const DEFAULT_PLACEHOLDER = '搜索'
|
||||
|
||||
const resetPlaceholder = (input: HTMLInputElement) => {
|
||||
input.placeholder = DEFAULT_PLACEHOLDER
|
||||
input.title = DEFAULT_PLACEHOLDER
|
||||
}
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'hideTrendingSearch',
|
||||
@ -12,14 +20,24 @@ export const component = defineComponentMetadata({
|
||||
},
|
||||
],
|
||||
entry: async () => {
|
||||
const input: HTMLInputElement = await select('input.nav-search-input', {
|
||||
queryInterval: 500,
|
||||
})
|
||||
|
||||
if (input) {
|
||||
resetPlaceholder(input)
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback to observer
|
||||
allMutations(records => {
|
||||
records.forEach(record => {
|
||||
if (
|
||||
record.target instanceof HTMLInputElement &&
|
||||
record.target.classList.contains('nav-search-input') &&
|
||||
record.target.placeholder !== '搜索'
|
||||
record.target.placeholder !== DEFAULT_PLACEHOLDER
|
||||
) {
|
||||
record.target.placeholder = '搜索'
|
||||
resetPlaceholder(record.target)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -0,0 +1 @@
|
||||
将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停.
|
||||
@ -27,10 +27,6 @@ const entry = async () => {
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'doubleClickControl',
|
||||
displayName: '启用双击控制',
|
||||
description: {
|
||||
'zh-CN':
|
||||
'将视频播放器的操作方式更改为: 单击显示 / 隐藏控制栏, 双击播放 / 暂停. 请注意不能和 `双击全屏` 一同使用.',
|
||||
},
|
||||
tags: [componentsTags.touch],
|
||||
enabledByDefault: navigator.maxTouchPoints > 0,
|
||||
urlInclude: playerUrls,
|
||||
|
||||
@ -57,7 +57,8 @@ export const loadKeyBindings = lodash.once((bindings: KeyBinding[]) => {
|
||||
return true
|
||||
})()
|
||||
if (
|
||||
(binding.action.ignoreFocus !== false || binding.action.ignoreTyping !== false) &&
|
||||
binding.action.ignoreFocus !== false &&
|
||||
binding.action.ignoreTyping !== false &&
|
||||
hasElementFocus
|
||||
) {
|
||||
return
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
- 如果希望映射到多种按键, 可以继续用空格隔开, 但注意组合键是固定的, 例如: 配置 `a b` 表示 `A` 或 `B` 键, 而配置 `shift a b` 就表示 `Shift + A` / `Shift + B`
|
||||
- 组合键是精确匹配的, 按下 `Ctrl + Shift + A` 不能触发配置为 `shift a` 的快捷键
|
||||
- 如果希望组合键可按可不按, 可以给它套上一个 `[]`, 例如 `[ctrl] shift a` 表示 `Ctrl + Shift +A` / `Shift + A`
|
||||
- b 站自带有一些快捷键, 修改本组件提供的相同动作快捷键不会影响 b 站自带的快捷键, 如果希望屏蔽掉 b 站自带的快捷键, 可以安装 `快捷键扩展 - 无动作` 插件, 并将无动作绑定到希望屏蔽的快捷键上. 例如希望用 `C` 键投币且不希望自带的 `W` 键触发投币, 则应该在组件里配置投币为 `c`, 无动作为 `w`
|
||||
|
||||
## 预设
|
||||
在第三列的表头中可以通过下拉框切换预设, 预设是一套固定的按键定义, 方便快速切换到用户更熟悉的按键风格中. 插件可以使用 `keymap.presets` 作为 key 添加新的预设.
|
||||
|
||||
@ -37,7 +37,8 @@ body:not(.preserve-feed-goods) .dyn-goods,
|
||||
.adcard,
|
||||
.palette-button-adcard,
|
||||
.palette-button-wrap .adcard-content,
|
||||
.video-card-ad-small {
|
||||
.video-card-ad-small,
|
||||
.search-all-list .video-list > *:has(.bili-video-card__info--ad) {
|
||||
display: none !important;
|
||||
}
|
||||
.recommend-list .rec-list > :not(.video-page-card) + .video-page-card {
|
||||
|
||||
@ -0,0 +1 @@
|
||||
禁用播放器的双击全屏功能.
|
||||
@ -0,0 +1,24 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { select } from '@/core/spin-query'
|
||||
import { preventEvent } from '@/core/utils'
|
||||
import { playerUrls } from '@/core/utils/urls'
|
||||
|
||||
let dispose: (() => void) | undefined
|
||||
const entry = async () => {
|
||||
const layer = (await select('.bpx-player-video-perch')) as HTMLElement
|
||||
if (!layer) {
|
||||
return
|
||||
}
|
||||
dispose = preventEvent(layer, 'dblclick')
|
||||
}
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'disableDoubleClickFullscreen',
|
||||
displayName: '禁用双击全屏',
|
||||
entry,
|
||||
reload: entry,
|
||||
unload: () => {
|
||||
dispose?.()
|
||||
},
|
||||
tags: [componentsTags.video],
|
||||
urlInclude: playerUrls,
|
||||
})
|
||||
@ -1,50 +0,0 @@
|
||||
import {
|
||||
defineOptionsMetadata,
|
||||
OptionsOfMetadata,
|
||||
defineComponentMetadata,
|
||||
} from '@/components/define'
|
||||
import { ComponentEntry } from '@/components/types'
|
||||
import { playerUrls } from '@/core/utils/urls'
|
||||
|
||||
const options = defineOptionsMetadata({
|
||||
preventSingleClick: {
|
||||
displayName: '双击时阻止单击事件',
|
||||
defaultValue: true,
|
||||
},
|
||||
})
|
||||
|
||||
export type Options = OptionsOfMetadata<typeof options>
|
||||
|
||||
const entry: ComponentEntry<Options> = async ({ settings }) => {
|
||||
const { videoChange } = await import('@/core/observer')
|
||||
videoChange(async () => {
|
||||
const { DoubleClickEvent } = await import('@/core/utils')
|
||||
const { playerAgent } = await import('@/components/video/player-agent')
|
||||
const playerArea = await playerAgent.query.danmakuTipLayer()
|
||||
if (playerArea === null) {
|
||||
console.error('playerArea not found')
|
||||
return
|
||||
}
|
||||
const className = 'double-click-fullscreen'
|
||||
if (!playerArea.classList.contains(className)) {
|
||||
playerArea.classList.add(className)
|
||||
const container = playerAgent.query.video.container.sync()
|
||||
const doubleClick = new DoubleClickEvent(
|
||||
() => playerAgent.fullscreen(),
|
||||
settings.options.preventSingleClick,
|
||||
)
|
||||
doubleClick.singleClickHandler = () => playerAgent.togglePlay()
|
||||
doubleClick.bind(container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'doubleClickFullscreen',
|
||||
displayName: '双击全屏',
|
||||
description: '为视频播放器启用双击全屏功能, 请注意不能和 `启用双击控制` 一同使用.',
|
||||
entry,
|
||||
tags: [componentsTags.video],
|
||||
options,
|
||||
urlInclude: playerUrls,
|
||||
})
|
||||
@ -8,10 +8,16 @@ import desc from './desc.md'
|
||||
import ScreenshotContainer from './VideoScreenshotContainer.vue'
|
||||
|
||||
export const VideoScreenshotDisabledClass = 'video-screenshot-disable'
|
||||
const entry = async () => {
|
||||
let screenShotsList: Vue & {
|
||||
screenshots: Screenshot[]
|
||||
let screenShotsList: Vue & {
|
||||
screenshots: Screenshot[]
|
||||
}
|
||||
const exitConfirmHandler = (e: BeforeUnloadEvent) => {
|
||||
if (screenShotsList?.screenshots.length > 0) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
const entry = async () => {
|
||||
addControlBarButton({
|
||||
name: 'takeScreenshot',
|
||||
displayName: '截图',
|
||||
@ -35,6 +41,7 @@ const entry = async () => {
|
||||
}
|
||||
},
|
||||
})
|
||||
window.addEventListener('beforeunload', exitConfirmHandler)
|
||||
}
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'videoScreenshot',
|
||||
@ -45,8 +52,14 @@ export const component = defineComponentMetadata({
|
||||
'zh-CN': desc,
|
||||
},
|
||||
urlInclude: playerUrls,
|
||||
reload: () => document.body.classList.remove(VideoScreenshotDisabledClass),
|
||||
unload: () => document.body.classList.add(VideoScreenshotDisabledClass),
|
||||
reload: () => {
|
||||
document.body.classList.remove(VideoScreenshotDisabledClass)
|
||||
window.addEventListener('beforeunload', exitConfirmHandler)
|
||||
},
|
||||
unload: () => {
|
||||
document.body.classList.add(VideoScreenshotDisabledClass)
|
||||
window.removeEventListener('beforeunload', exitConfirmHandler)
|
||||
},
|
||||
plugin: {
|
||||
displayName: '视频截图 - 快捷键支持',
|
||||
setup: ({ addData }) => {
|
||||
|
||||
46
registry/lib/plugins/style/custom-navbar-pgc/index.ts
Normal file
46
registry/lib/plugins/style/custom-navbar-pgc/index.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { PluginMetadata } from '@/plugins/plugin'
|
||||
import type { CustomNavbarItemInit } from '../../../components/style/custom-navbar/custom-navbar-item'
|
||||
|
||||
export const plugin: PluginMetadata = {
|
||||
name: 'customNavbar.items.pgc',
|
||||
displayName: '自定义顶栏 - 版权内容',
|
||||
description: '为自定义顶栏扩充版权内容相关的快速入口, 包括国创 / 电影 / 电视剧 /综艺 / 纪录片',
|
||||
async setup({ addData }) {
|
||||
addData('customNavbar.items', (items: CustomNavbarItemInit[]) => {
|
||||
const pgcItems = [
|
||||
{
|
||||
name: 'guochuang',
|
||||
displayName: '国创',
|
||||
href: 'https://www.bilibili.com/guochuang/',
|
||||
},
|
||||
{
|
||||
name: 'movie',
|
||||
displayName: '电影',
|
||||
href: 'https://www.bilibili.com/movie/',
|
||||
},
|
||||
{
|
||||
name: 'tv',
|
||||
displayName: '电视剧',
|
||||
href: 'https://www.bilibili.com/tv/',
|
||||
},
|
||||
{
|
||||
name: 'variety',
|
||||
displayName: '综艺',
|
||||
href: 'https://www.bilibili.com/variety/',
|
||||
},
|
||||
{
|
||||
name: 'documentary',
|
||||
displayName: '纪录片',
|
||||
href: 'https://www.bilibili.com/documentary/',
|
||||
},
|
||||
]
|
||||
items.push(
|
||||
...pgcItems.map(item => ({
|
||||
...item,
|
||||
content: item.displayName,
|
||||
active: document.URL.startsWith(item.href),
|
||||
})),
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { DownloadPackage, PackageEntry } from '@/core/download'
|
||||
import { meta } from '@/core/meta'
|
||||
import { getComponentSettings } from '@/core/settings'
|
||||
import { Toast } from '@/core/toast'
|
||||
import { formatPercent } from '@/core/utils/formatters'
|
||||
import { formatFileSize, formatPercent } from '@/core/utils/formatters'
|
||||
import { title as pluginTitle } from '.'
|
||||
import type { Options } from '../../../../components/video/download'
|
||||
import { DownloadVideoAction } from '../../../../components/video/download/types'
|
||||
@ -139,6 +139,10 @@ export async function run(action: DownloadVideoAction, muxWithMetadata: boolean)
|
||||
throw new Error('仅支持 DASH 格式视频和音频')
|
||||
}
|
||||
|
||||
if (video.size + audio.size > 4294967295) {
|
||||
throw new Error(`仅支持合并 4GB 内的音视频(${formatFileSize(video.size + audio.size)})`)
|
||||
}
|
||||
|
||||
await single(
|
||||
video.title,
|
||||
video.url,
|
||||
|
||||
@ -19,7 +19,7 @@ export const plugin: PluginMetadata = {
|
||||
outputs.push({
|
||||
name: 'wasm',
|
||||
displayName: 'WASM',
|
||||
description: `${desc}。运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件。`,
|
||||
description: `${desc}。运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件。由于浏览器限制,仅支持合并 4GB 以内的音视频。`,
|
||||
runAction: async (action, instance) => {
|
||||
try {
|
||||
await run(action, instance.muxWithMetadata)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.10.0",
|
||||
"version": "2.10.1",
|
||||
"author": "Grant Howard, Coulomb-G",
|
||||
"copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)",
|
||||
"license": "MIT",
|
||||
|
||||
@ -15,6 +15,12 @@ const feedsCardTypeMap = {
|
||||
DynamicTypeArticle: feedsCardTypes.column,
|
||||
DynamicTypeMusic: feedsCardTypes.audio,
|
||||
DynamicTypeLiveRcmd: feedsCardTypes.liveRecord,
|
||||
DynamicTypeCourses: feedsCardTypes.courses,
|
||||
DynamicTypeOpus: feedsCardTypes.textWithImages,
|
||||
DynamicTypeLive: feedsCardTypes.live,
|
||||
DynamicTypeMedialist: feedsCardTypes.mediaList,
|
||||
DynamicTypeSubscription: feedsCardTypes.mediaList,
|
||||
DynamicTypeUgcSeason: feedsCardTypes.ugcSeason,
|
||||
}
|
||||
|
||||
const combineText = (...texts: string[]) =>
|
||||
@ -23,7 +29,7 @@ const combineText = (...texts: string[]) =>
|
||||
.join('\n')
|
||||
.trim()
|
||||
const getType = (rawType: string): FeedsCardType =>
|
||||
feedsCardTypeMap[pascalCase(rawType)] ?? feedsCardTypeMap.DynamicTypeWord
|
||||
feedsCardTypeMap[pascalCase(rawType)] ?? feedsCardTypes.unknown
|
||||
const getText = (dynamicModule: any, cardType: FeedsCardType) => {
|
||||
const isOpusModule = Object.hasOwn(dynamicModule, 'paragraphs')
|
||||
if (isOpusModule) {
|
||||
|
||||
@ -15,6 +15,10 @@ export interface RepostFeedsCardType extends FeedsCardType {
|
||||
name: '转发'
|
||||
}
|
||||
export const feedsCardTypes = {
|
||||
unknown: {
|
||||
id: 0,
|
||||
name: '未知',
|
||||
},
|
||||
repost: {
|
||||
id: 1,
|
||||
name: '转发',
|
||||
@ -78,8 +82,20 @@ export const feedsCardTypes = {
|
||||
id: 4300,
|
||||
name: '收藏夹',
|
||||
},
|
||||
courses: {
|
||||
id: 2044,
|
||||
name: '课程',
|
||||
},
|
||||
live: {
|
||||
id: 2045,
|
||||
name: '直播',
|
||||
},
|
||||
ugcSeason: {
|
||||
id: 2046,
|
||||
name: '合集',
|
||||
},
|
||||
liveRecord: {
|
||||
id: 2047, // FIXME: 暂时随便写个 id 了, 这个东西目前找不到 type
|
||||
id: 2047,
|
||||
name: '开播记录',
|
||||
},
|
||||
} satisfies Record<string, FeedsCardType>
|
||||
|
||||
@ -73,7 +73,6 @@ export default Vue.extend({
|
||||
--color: #eee;
|
||||
}
|
||||
.launch-bar-suggest-list {
|
||||
transition: 0.2s ease-out;
|
||||
top: calc(100% + 8px);
|
||||
max-height: calc(80vh - 16px - #{$barHeight});
|
||||
@include no-scrollbar();
|
||||
|
||||
@ -333,7 +333,7 @@ export default Vue.extend({
|
||||
width: 100%;
|
||||
transform: translateX(-50%) translateY(-4px);
|
||||
pointer-events: none;
|
||||
// transition: 0.2s ease-out;
|
||||
transition: 0.2s all ease-out;
|
||||
border: 1px solid #8882;
|
||||
white-space: nowrap;
|
||||
border-radius: 8px;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { attributes } from '@/core/observer'
|
||||
import { select } from '@/core/spin-query'
|
||||
import { playerReady, preventEvent } from '@/core/utils'
|
||||
import { playerReady } from '@/core/utils'
|
||||
import { createPlayerModeChangeEvent, PlayerMode } from './events'
|
||||
|
||||
/** 播放器模式标记同步 */
|
||||
@ -36,19 +36,8 @@ const playerModePolyfill = async () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 移除 3.x 的双击全屏.
|
||||
* 如果以后视频区兼容了弹幕点赞层, 需要将双击全屏组件更换为阻止双击全屏, 并取消对此函数的使用.
|
||||
*/
|
||||
const doubleClickPolyfill = async () => {
|
||||
const layer = (await select('.bpx-player-video-perch')) as HTMLElement
|
||||
if (!layer) {
|
||||
return
|
||||
}
|
||||
preventEvent(layer, 'dblclick')
|
||||
}
|
||||
|
||||
/** 番剧 & 视频播放器 (BPX) 通用 polyfill */
|
||||
export const bpxPlayerPolyfill = lodash.once(async () => {
|
||||
playerModePolyfill()
|
||||
doubleClickPolyfill()
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user