mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Merge tag 'v2.10.0-preview' into preview-fixes
This commit is contained in:
commit
494be26889
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -51,6 +51,7 @@
|
||||
"Fullscreen",
|
||||
"githubusercontent",
|
||||
"Greasemonkey",
|
||||
"guochuang",
|
||||
"haruna",
|
||||
"hdslb",
|
||||
"HEVC",
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
**注意事项**
|
||||
- **⚠ 使用正式版 (GitHub 源) 和预览版须翻墙.**
|
||||
- 默认不预装任何组件, 需要在按[设置](#设置)中的说明添加感兴趣的功能; 默认会屏蔽双击全屏, 如有需要可以安装 `双击全屏` 组件来恢复.
|
||||
- 默认不预装任何组件, 需要在按[设置](#设置)中的说明添加感兴趣的功能.
|
||||
- 这个是一个综合性的脚本, 如果只是想下载视频建议去 [GreasyFork](https://greasyfork.org/zh-CN/scripts/by-site/bilibili.com) 找个更专业的.
|
||||
- 对性能有较大影响, 详见[配置要求](#配置).
|
||||
- 默认不对未登录的状态做适配.
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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`
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -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 & {
|
||||
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)
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user