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
35578ac474
@ -13,7 +13,7 @@
|
||||
"id": "feature",
|
||||
"attributes": {
|
||||
"label": "对应功能",
|
||||
"description": "(指本脚本的某项具体功能, 不是指 b 站的) 可以在设置中尝试开启 / 关闭某项功能来排查. 最好能附上功能的 Commit 值 (在设置里功能选项的底部).\n<img src=\"https://user-images.githubusercontent.com/26504152/152666017-8a5acabc-2ad1-47ef-b0a2-cd5c54c867ab.jpg\" width=\"400\">\n请注意: 以下功能已不再维护 (不再修复 bug 和添加新功能), 但是你仍然可以为其提供 Pull Request.\n- 直播间自动抽奖\n- 默认播放器模式\n- 播放器置顶\n- 播放器定位\n",
|
||||
"description": "(指本脚本的某项具体功能, 不是指 b 站的) 可以在设置中尝试开启 / 关闭某项功能来排查. 最好能附上功能的 Commit 值 (在设置里功能选项的底部).\n<img src=\"https://user-images.githubusercontent.com/26504152/152666017-8a5acabc-2ad1-47ef-b0a2-cd5c54c867ab.jpg\" width=\"400\">\n如果组件包含作者的信息 (by @xxx), 请在这里 at 他们\n请注意: 以下功能已不再维护 (不再修复 bug 和添加新功能), 但是你仍然可以为其提供 Pull Request.\n- 直播间自动抽奖\n- 默认播放器模式\n- 播放器置顶\n- 播放器定位\n",
|
||||
"placeholder": "请输入"
|
||||
},
|
||||
"validations": {
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -13,6 +13,7 @@ body:
|
||||
description: |
|
||||
(指本脚本的某项具体功能, 不是指 b 站的) 可以在设置中尝试开启 / 关闭某项功能来排查. 最好能附上功能的 Commit 值 (在设置里功能选项的底部).
|
||||
<img src="https://user-images.githubusercontent.com/26504152/152666017-8a5acabc-2ad1-47ef-b0a2-cd5c54c867ab.jpg" width="400">
|
||||
如果组件包含作者的信息 (by @xxx), 请在这里 at 他们
|
||||
请注意: 以下功能已不再维护 (不再修复 bug 和添加新功能), 但是你仍然可以为其提供 Pull Request.
|
||||
- 直播间自动抽奖
|
||||
- 默认播放器模式
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ dist/profile.json
|
||||
dist/bilibili-evolved.dev.user.js
|
||||
registry/dist/doc.js
|
||||
dev-tools/**/dist/
|
||||
.idea
|
||||
|
||||
91
CHANGELOG.md
91
CHANGELOG.md
@ -1,5 +1,96 @@
|
||||
# 更新日志
|
||||
|
||||
## v2.8.5 / v2.8.5-preview
|
||||
`2023-09-24`
|
||||
|
||||
✨新增
|
||||
- 新增组件 `自定义字体`. (PR #4406 by [Tinhone](https://github.com/Tinhone))
|
||||
> 使用组件提供的字体设置覆盖原版的主站字体,并使主站字体可被自定义。字体设置写法请参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family) 、默认设置与设置说明
|
||||
|
||||
- `简化直播间` 适配了新版 PK 条. (PR #4439 by [Pencil](https://github.com/pencilqaq))
|
||||
|
||||
- `下载视频` 支持配置 DASH 格式下的文件扩展名. (PR #4449 by [小傅Fox](https://github.com/xfoxfu))
|
||||
|
||||
|
||||
<details>
|
||||
<summary>正式版用户将获得 v2.8.0-preview ~ v2.8.4-preview 的所有新功能, 点击展开查看</summary>
|
||||
|
||||
- `清爽首页` 改进:
|
||||
- 支持自定义板块的布局和可见性. (操作方式和自定义顶栏那个差不多)
|
||||
- 番剧时间表优化样式, 增加翻页按钮.
|
||||
|
||||
<div>
|
||||
<img height="400" src="https://user-images.githubusercontent.com/26504152/242905984-895cb72c-b344-40c3-91a0-2a6b20d5f783.png">
|
||||
<img height="400" src="https://user-images.githubusercontent.com/26504152/242905640-cbc948f1-734e-46f2-96a7-d57787b7cf47.png">
|
||||
</div>
|
||||
|
||||
- 新增功能 `首页净化`. (PR #4153 by [RieN](https://github.com/rien7))
|
||||
> 删除首页特定类型的卡片.
|
||||
|
||||
- `自定义顶栏` 增加 `创作中心` 入口, `排行` 新增 `全站音乐榜` 和 `短剧榜` 的入口. (#4101, PR #4154 by [星海](https://github.com/lovelyCARDINAL), PR #4155 by [星海](https://github.com/lovelyCARDINAL))
|
||||
- `播放器置顶(新)` 增加选项 `顶部留白`. (#4152, PR #4165 by [Ziu](https://github.com/ZiuChen))
|
||||
- `播放器置顶(新)` 的标题改为放置到播放器和点赞中间. (PR #4208 by [LockRim](https://github.com/LockRim))
|
||||
- `显示视频投稿时间` 支持转义字符. (#4160, PR #4167 by [呼乎户](https://github.com/wisokey))
|
||||
- `隐藏视频推荐` 支持稍后再看和收藏夹播放页, 并适配 bpx 播放器. (#4174)
|
||||
- 新增功能 `隐藏记笔记` 和 `隐藏稿件投诉`. (#4124)
|
||||
- 优化了 `自定义顶栏` 中订阅在筛选时的 API 调用. (#4120)
|
||||
- 优化粗体的显示: 优先调用 Semibold 字重, 若字体不支持则使用 Bold 字重.
|
||||
- `自定义顶栏` 增加选项:
|
||||
- 支持自定义消息提醒样式, 可设置为 `数字`, `点状` 或 `隐藏`. (#4125)
|
||||
- 支持自定义搜索栏宽度. (#4112)
|
||||
- 搜索在纯数字输入时, 增加对 UID 和直播间的搜索. (#677)
|
||||
- `网址参数清理` 更新对直播间的支持. (#1459)
|
||||
- `自动点赞` 转为由 [CrazyboyQCD](https://github.com/CrazyboyQCD) 维护, 支持手动控制点赞和黑名单功能. (PR #4343, PR #4358 by [CrazyboyQCD](https://github.com/CrazyboyQCD))
|
||||
|
||||
- `简化直播间` 支持隐藏荣耀等级勋章. (PR #4348 by [CrunchyShark](https://github.com/CrunchyShark944))
|
||||
- 在设置面板中的组件管理等面板中, 搜索框移动至已安装列表的上方, 更符合直觉. (#3806)
|
||||
- 支持从 Tampermonkey 的菜单中唤起功能和设置面板. (#4170)
|
||||
- 搜索栏中添加了导入 / 导出设置的操作. (#4170)
|
||||
- `自定义顶栏` 新增选项 `链接对齐样式`, 可以自定义纯链接弹窗内链接文字的对齐样式. (PR #4365 by [Tinhone](https://github.com/Tinhone))
|
||||
- `简化评论区` 支持独立控制简化选项, 并支持隐藏粉丝勋章和活动横幅. (仅支持新版评论区) (#2381)
|
||||
- `清爽首页` 设置为隐藏的版块现在将彻底销毁, 减少资源占用.
|
||||
- `禁用特殊弹幕样式` 支持禁用大会员弹幕. (#4227)
|
||||
- `下载视频` 在批量下载番剧时, 支持下载多个不同板块的选集. (#2834)
|
||||
- 新增功能 `全屏直播礼物简化`. (PR #4306 by [TimmyOVO](https://github.com/TimmyOVO))
|
||||
|
||||
> 移除全屏观看直播时的底部礼物栏
|
||||
|
||||
- 新增功能 `评论区 IP 属地显示`. (PR #4331, PR #4334 by [Light_Quanta](https://github.com/LightQuanta))
|
||||
|
||||
> 在评论区显示评论的IP属地信息
|
||||
|
||||
- 新增功能 `直播间网页全屏自适应`. (#4216)
|
||||
|
||||
> 在直播网页全屏时, 自动调整侧边栏的宽度, 使得视频区域的比例和视频源相匹配, 达到无黑边的效果. 如果在侧边栏的边缘拖动, 可以自定义侧边栏的固定宽度, 双击边缘可以还原到自动宽度.
|
||||
>
|
||||
> - `侧边栏最大宽度 (px)`: 限制侧边栏可被拉伸到的最大宽度. (最小宽度固定为 190px, 再小的话布局就要出问题了)
|
||||
>
|
||||
> > 注意, 由于有最大宽度和最小宽度的限制, 部分窗口尺寸下仍然无法做到无黑边.
|
||||
|
||||
- 新增功能 `关注时间显示`. (PR #4352 by [Light_Quanta](https://github.com/LightQuanta))
|
||||
|
||||
> 在个人空间的粉丝/关注列表显示关注的具体时间
|
||||
|
||||
- 新增功能 `自动移出稍后再看`.
|
||||
|
||||
> 在稍后再看页面播放结束时, 自动将当前视频移出稍后再看.
|
||||
> 注意:
|
||||
> - 一定要播放结束, 快结束时手动切走不算
|
||||
> - b 站的稍后再看列表不会实时刷新
|
||||
|
||||
- 新增功能 `相簿发布时间显示`. (PR #4362 by [Light_Quanta](https://github.com/LightQuanta))
|
||||
|
||||
> 在个人空间的相簿界面显示相簿的发布时间
|
||||
|
||||
</details>
|
||||
|
||||
🐛修复
|
||||
- 修复 `禁止滚轮调音量` 在网页全屏下失效. (#4381).
|
||||
- 修复 Feeds API 无法解析新版图文动态的文字内容. (主要是动态过滤器会受影响) (#4409)
|
||||
- 修复 `选集区域优化` 在部分视频合集页面上无法使用 <kbd>Alt</kbd> 来切换折叠. (#4429)
|
||||
- 修复被转发图文动态的 `详情 >` 功能失效. (PR #4452 by [sunfkny](https://github.com/sunfkny))
|
||||
|
||||
|
||||
## v2.8.4-preview
|
||||
`2023-09-07`
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ https://afdian.net/@the1812?tab=sponsor
|
||||
|
||||
| 时间 | 用户名 | 单号后4位 | 金额 |
|
||||
| ------------------- | --------------------- | --------- | ------- |
|
||||
| 2023.09.22 04:41:59 | S*y | 7595 | ¥2.00 |
|
||||
| 2023.08.29 12:38:40 | 匿名 | 3584 | ¥2.33 |
|
||||
| 2023.08.27 05:41:58 | 匿名 | 3000 | ¥20.00 |
|
||||
| 2023.08.27 05:41:35 | 匿名 | 2195 | ¥20.00 |
|
||||
|
||||
@ -191,6 +191,14 @@
|
||||
"fullRelativePath": "../../registry/dist/components/style/clear-home.js",
|
||||
"fullAbsolutePath": "registry/dist/components/style/clear-home.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "customFontFamily",
|
||||
"displayName": "自定义字体",
|
||||
"description": "by [@Tinhone](https://github.com/Tinhone)\n\n使用组件提供的字体设置覆盖原版的主站字体,并使主站字体可被自定义。字体设置写法请参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family) 、默认设置与设置说明",
|
||||
"fullRelativePath": "../../registry/dist/components/style/custom-font-family.js",
|
||||
"fullAbsolutePath": "registry/dist/components/style/custom-font-family.js"
|
||||
},
|
||||
{
|
||||
"type": "component",
|
||||
"name": "customNavbar",
|
||||
@ -779,7 +787,7 @@
|
||||
"type": "component",
|
||||
"name": "playerIntersectionActions",
|
||||
"displayName": "播放器位置动作",
|
||||
"description": "by [@FoundTheWOUT](https://github.com/FoundTheWOUT)\n\n设置当播放器移出视图的位置变化时执行的动作.",
|
||||
"description": "by [@Waua](https://github.com/FoundTheWOUT)\n\n设置当播放器移出视图的位置变化时执行的动作.",
|
||||
"fullRelativePath": "../../registry/dist/components/video/player/intersection-actions.js",
|
||||
"fullAbsolutePath": "registry/dist/components/video/player/intersection-actions.js"
|
||||
},
|
||||
|
||||
@ -233,6 +233,17 @@ by [@RieN7](https://github.com/rien7)
|
||||
|
||||
删除首页特定类型的卡片
|
||||
|
||||
### [自定义字体](../../registry/dist/components/style/custom-font-family.js)
|
||||
`customFontFamily`
|
||||
|
||||
**jsDelivr:** [`Stable`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@master/registry/dist/components/style/custom-font-family.js) / [`Preview`](https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/registry/dist/components/style/custom-font-family.js)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/style/custom-font-family.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/style/custom-font-family.js)
|
||||
|
||||
by [@Tinhone](https://github.com/Tinhone)
|
||||
|
||||
使用组件提供的字体设置覆盖原版的主站字体,并使主站字体可被自定义。字体设置写法请参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family) 、默认设置与设置说明
|
||||
|
||||
### [自定义顶栏](../../registry/dist/components/style/custom-navbar.js)
|
||||
`customNavbar`
|
||||
|
||||
@ -1050,7 +1061,7 @@ by [@JLoeve](https://github.com/LonelySteve)
|
||||
|
||||
**GitHub:** [`Stable`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/registry/dist/components/video/player/intersection-actions.js) / [`Preview`](https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/registry/dist/components/video/player/intersection-actions.js)
|
||||
|
||||
by [@FoundTheWOUT](https://github.com/FoundTheWOUT)
|
||||
by [@Waua](https://github.com/FoundTheWOUT)
|
||||
|
||||
设置当播放器移出视图的位置变化时执行的动作.
|
||||
|
||||
|
||||
@ -69,7 +69,10 @@ const entry = async () => {
|
||||
return
|
||||
}
|
||||
if (postContent.classList.contains('repost') || card.type === feedsCardTypes.repost) {
|
||||
const contents = dq(postContent, '.content, .bili-dyn-content__orig__desc') as HTMLElement
|
||||
const contents = dq(
|
||||
postContent,
|
||||
'.content, .bili-dyn-content__orig__desc, .dyn-card-opus__summary',
|
||||
) as HTMLElement
|
||||
if (!contents) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -5,20 +5,15 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { DefaultWidget } from '@/ui'
|
||||
import { getOriginalLiveroomUrl } from './get-original-liveroom-url'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
DefaultWidget,
|
||||
},
|
||||
data() {
|
||||
const match = document.URL.match(/^https:\/\/live\.bilibili\.com\/([\d]+)/)
|
||||
if (!match) {
|
||||
return {
|
||||
href: document.URL,
|
||||
}
|
||||
}
|
||||
return {
|
||||
href: `https://live.bilibili.com/blanc/${match[1]}`,
|
||||
href: getOriginalLiveroomUrl(document.URL),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* 如果成功从参数 url 中捕获到直播间号,那么返回原版直播间页面链接,否则返回参数 url
|
||||
* @param url 直播间页面链接
|
||||
*/
|
||||
export const getOriginalLiveroomUrl = (url: string): string => {
|
||||
const match = url.match(/^https:\/\/live\.bilibili\.com\/([\d]+)/)
|
||||
return match ? `https://live.bilibili.com/blanc/${match[1]}` : url
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { matchUrlPattern } from '@/core/utils'
|
||||
import { isIframe, isNotHtml, matchUrlPattern } from '@/core/utils'
|
||||
import { getOriginalLiveroomUrl } from './get-original-liveroom-url'
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'originalLiveroom',
|
||||
@ -7,7 +8,20 @@ export const component = defineComponentMetadata({
|
||||
description:
|
||||
'在直播间中提供返回原版直播间的按钮, 原版直播间将无视活动皮肤, 强制使用标准的直播页面.',
|
||||
tags: [componentsTags.live],
|
||||
entry: none,
|
||||
entry: ({ settings }) => {
|
||||
if (isNotHtml() || isIframe()) {
|
||||
return
|
||||
}
|
||||
if (settings.options.defaultBack) {
|
||||
window.location.assign(getOriginalLiveroomUrl(document.URL))
|
||||
}
|
||||
},
|
||||
options: {
|
||||
defaultBack: {
|
||||
displayName: '默认返回原版直播间',
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
urlInclude: [
|
||||
// 不能直接用 liveUrls, 那个是带 blanc 检测的
|
||||
/^https:\/\/live\.bilibili\.com\/[\d]+/,
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
$name: 'custom-font-family';
|
||||
|
||||
html[#{$name}--options--disable-quotation-mark-text-indent='true']
|
||||
:is(
|
||||
p[title^='「'],
|
||||
p[title^='『'],
|
||||
p[title^='【'],
|
||||
h1[title^='「'],
|
||||
h1[title^='『'],
|
||||
h1[title^='【'],
|
||||
h3[title^='「'],
|
||||
h3[title^='『'],
|
||||
h3[title^='【']
|
||||
) {
|
||||
text-indent: initial !important;
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div class="custom-font-family-extra-options-entry">
|
||||
<VButton ref="button" @mouseover="loadExtraOptions()" @click="toggleExtraOptionsDisplay()">
|
||||
字体设置<VIcon icon="right-arrow" :size="16"></VIcon>
|
||||
</VButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { VIcon, VButton } from '@/ui'
|
||||
import {
|
||||
setTriggerElement,
|
||||
getExtraOptionsLoadState,
|
||||
loadExtraOptions,
|
||||
toggleExtraOptionsDisplay,
|
||||
} from './vm'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
VIcon,
|
||||
VButton,
|
||||
},
|
||||
|
||||
methods: {
|
||||
async loadExtraOptions() {
|
||||
const isLoaded = await getExtraOptionsLoadState()
|
||||
if (!isLoaded) {
|
||||
await loadExtraOptions()
|
||||
const triggerButton = this.$refs.button.$el as HTMLElement
|
||||
setTriggerElement(triggerButton)
|
||||
}
|
||||
},
|
||||
toggleExtraOptionsDisplay,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.custom-font-family-extra-options-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,109 @@
|
||||
@import 'common';
|
||||
|
||||
$pref: 'eop';
|
||||
$prefH: 'eop-h';
|
||||
$prefHL: 'eop-h-l';
|
||||
$prefHR: 'eop-h-r';
|
||||
$prefC: 'eop-c';
|
||||
$prefCS: 'eop-c-s';
|
||||
|
||||
$panelPadding: 22px;
|
||||
|
||||
@mixin extra-options-panel {
|
||||
&.extra-options-panel {
|
||||
@include popup();
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 500px;
|
||||
max-height: 80vh;
|
||||
padding: $panelPadding 0;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translateX(-50%) translateY(-50%) scale(0.95);
|
||||
transition: all 0.2s ease-out;
|
||||
font-size: 14px;
|
||||
z-index: 100002;
|
||||
|
||||
&.open {
|
||||
transform: translateX(-50%) translateY(-50%) scale(1);
|
||||
}
|
||||
|
||||
&.peek {
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
> .#{$pref}-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 $panelPadding 18px $panelPadding;
|
||||
flex-shrink: 0;
|
||||
|
||||
> .#{$prefH}-left {
|
||||
display: flex;
|
||||
column-gap: 4px;
|
||||
|
||||
> .#{$prefHL}-title {
|
||||
@include semi-bold();
|
||||
font-size: 19px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$prefH}-right {
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
|
||||
> [class*='#{$prefHR}'] {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-out;
|
||||
|
||||
&:hover {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$pref}-separator {
|
||||
height: 1px;
|
||||
margin: 0 $panelPadding;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
flex-shrink: 0;
|
||||
|
||||
body.dark & {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$pref}-content {
|
||||
padding: 0 $panelPadding;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
> .#{$prefC}-section {
|
||||
margin: 18px 0;
|
||||
|
||||
&:nth-child(1):nth-last-child(1) {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
> .#{$prefCS}-title {
|
||||
margin-bottom: 2px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
> .#{$prefCS}-description {
|
||||
margin-bottom: 8px;
|
||||
opacity: 0.6;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
> .#{$prefCS}-input {
|
||||
@include h-center();
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<VPopup
|
||||
ref="popup"
|
||||
v-model="popupOpen"
|
||||
class="custom-font-family-extra-options-panel extra-options-panel"
|
||||
fixed
|
||||
:lazy="false"
|
||||
:trigger-element="triggerElement"
|
||||
:class="{ peek: isPeeking }"
|
||||
>
|
||||
<div class="eop-header">
|
||||
<div class="eop-h-left">
|
||||
<VIcon class="eop-h-l-symbol" icon="mdi-format-font" :size="24"></VIcon>
|
||||
<div class="eop-h-l-title">字体设置</div>
|
||||
</div>
|
||||
|
||||
<div class="eop-h-right">
|
||||
<VIcon
|
||||
class="eop-h-r-reset"
|
||||
title="重置面板中的所有选项为默认值"
|
||||
icon="mdi-cog-sync-outline"
|
||||
:size="24"
|
||||
@click="confirmResetOptions()"
|
||||
></VIcon>
|
||||
<VIcon
|
||||
class="eop-h-r-peek"
|
||||
title="透视"
|
||||
icon="mdi-eye-outline"
|
||||
:size="24"
|
||||
@mouseover="mouseOnPeekIcon = true"
|
||||
@mouseout="mouseOnPeekIcon = false"
|
||||
></VIcon>
|
||||
<VIcon
|
||||
class="eop-h-r-close"
|
||||
title="关闭"
|
||||
icon="mdi-close"
|
||||
:size="24"
|
||||
@click="popupOpen = false"
|
||||
></VIcon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="eop-separator"></div>
|
||||
|
||||
<div class="eop-content">
|
||||
<div class="eop-c-section">
|
||||
<div class="eop-c-s-title">自定义字体</div>
|
||||
<div class="eop-c-s-description">输入字体,不同字体之间必须以英文逗号分隔</div>
|
||||
<div class="eop-c-s-input input-font-family">
|
||||
<TextArea v-model="inputFontFamily" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VPopup>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { VPopup, VIcon, TextArea } from '@/ui'
|
||||
import { getComponentSettings } from '@/core/settings'
|
||||
import { delay } from '@/core/utils'
|
||||
import { useScopedConsole } from '@/core/utils/log'
|
||||
import { fontFamilyDefaultValue } from '../font-family-default-value'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
VPopup,
|
||||
VIcon,
|
||||
TextArea,
|
||||
},
|
||||
|
||||
props: {
|
||||
triggerElement: {
|
||||
type: HTMLElement,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
popupOpen: false,
|
||||
isPeeking: false,
|
||||
mouseOnPeekIcon: false,
|
||||
// 设置 inputFontFamily 初始值为组件 fontFamily 选项的值
|
||||
inputFontFamily: getComponentSettings('customFontFamily').options.fontFamily,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
// 监听 inputFontFamily 修改动作,实时修改组件 fontFamily 选项为 inputFontFamily 修改后的新值,并拥有 500ms 防抖
|
||||
inputFontFamily: lodash.debounce(value => {
|
||||
getComponentSettings('customFontFamily').options.fontFamily = value
|
||||
}, 500),
|
||||
|
||||
async mouseOnPeekIcon(value: boolean) {
|
||||
if (!value) {
|
||||
this.isPeeking = false
|
||||
return
|
||||
}
|
||||
if (value) {
|
||||
await delay(200)
|
||||
}
|
||||
if (this.mouseOnPeekIcon) {
|
||||
this.isPeeking = true
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
confirmResetOptions() {
|
||||
if (confirm('确定将面板中的所有选项重置为默认值吗?')) {
|
||||
this.resetOptions()
|
||||
}
|
||||
},
|
||||
|
||||
resetOptions() {
|
||||
getComponentSettings('customFontFamily').options.fontFamily = fontFamilyDefaultValue
|
||||
this.inputFontFamily = fontFamilyDefaultValue
|
||||
const console = useScopedConsole('自定义字体')
|
||||
console.log('已将字体设置面板中的所有选项重置为默认值')
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './extra-options-panel';
|
||||
|
||||
.custom-font-family-extra-options-panel {
|
||||
@include extra-options-panel;
|
||||
|
||||
> .eop-content > .eop-c-section > .eop-c-s-input.input-font-family .be-text-area {
|
||||
min-height: 160px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,24 @@
|
||||
import { mountVueComponent } from '@/core/utils'
|
||||
|
||||
let extraOptionsVm: Vue & {
|
||||
popupOpen: boolean
|
||||
triggerElement: HTMLElement
|
||||
}
|
||||
|
||||
export const setTriggerElement = (element: HTMLElement) => {
|
||||
extraOptionsVm.triggerElement = element
|
||||
}
|
||||
|
||||
export const getExtraOptionsLoadState = async () => {
|
||||
return Boolean(extraOptionsVm)
|
||||
}
|
||||
|
||||
export const loadExtraOptions = async () => {
|
||||
const extraOptions = await import('./panel.vue').then(m => m.default)
|
||||
extraOptionsVm = mountVueComponent(extraOptions)
|
||||
document.body.insertAdjacentElement('beforeend', extraOptionsVm.$el)
|
||||
}
|
||||
|
||||
export const toggleExtraOptionsDisplay = async () => {
|
||||
extraOptionsVm.popupOpen = !extraOptionsVm.popupOpen
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
export const fontFamilyDefaultValue =
|
||||
'Microsoft Yahei, Helvetica Neue, Helvetica, Arial, Hiragino Sans GB, Heiti SC, WenQuanYi Micro Hei'
|
||||
133
registry/lib/components/style/custom-font-family/index.ts
Normal file
133
registry/lib/components/style/custom-font-family/index.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import { addComponentListener } from '@/core/settings'
|
||||
import { fontFamilyDefaultValue } from './font-family-default-value'
|
||||
|
||||
const docElement = document.documentElement
|
||||
|
||||
const kebabName = 'custom-font-family'
|
||||
|
||||
const camelName = 'customFontFamily'
|
||||
|
||||
const name = camelName
|
||||
|
||||
const displayName = '自定义字体'
|
||||
|
||||
const description = {
|
||||
'zh-CN':
|
||||
'使用组件提供的字体设置覆盖原版的主站字体,并使主站字体可被自定义。字体设置写法请参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family) 、默认设置与设置说明',
|
||||
}
|
||||
|
||||
const tags = [componentsTags.style, componentsTags.general]
|
||||
|
||||
const entry = () => {
|
||||
addComponentListener(
|
||||
`${name}.fontFamily`,
|
||||
(value: string) => {
|
||||
if (!value) {
|
||||
docElement.setAttribute(`${kebabName}--detect--is-input-empty`, 'true')
|
||||
return
|
||||
}
|
||||
docElement.style.setProperty(`--${kebabName}--options--font-family`, `${value}`)
|
||||
docElement.setAttribute(`${kebabName}--detect--is-input-empty`, 'false')
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
addComponentListener(
|
||||
`${name}.disableQuotationMarkTextIndent`,
|
||||
(value: boolean) => {
|
||||
docElement.setAttribute(
|
||||
`${kebabName}--options--disable-quotation-mark-text-indent`,
|
||||
`${value}`,
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
const onOptionNames = [
|
||||
{ camel: 'onOrnament', kebab: 'on-ornament' },
|
||||
{ camel: 'onFansMedal', kebab: 'on-fans-medal' },
|
||||
{ camel: 'onDanmaku', kebab: 'on-danmaku' },
|
||||
{ camel: 'onIconFont', kebab: 'on-icon-font' },
|
||||
{ camel: 'onColumn', kebab: 'on-column' },
|
||||
{ camel: 'onScore', kebab: 'on-score' },
|
||||
]
|
||||
|
||||
onOptionNames.forEach(onOptionName => {
|
||||
addComponentListener(
|
||||
`${name}.${onOptionName.camel}`,
|
||||
(value: boolean) => {
|
||||
docElement.setAttribute(`${kebabName}--options--${onOptionName.kebab}`, `${value}`)
|
||||
},
|
||||
true,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const options = {
|
||||
fontFamily: {
|
||||
displayName: '字体',
|
||||
defaultValue: fontFamilyDefaultValue,
|
||||
hidden: true,
|
||||
},
|
||||
disableQuotationMarkTextIndent: {
|
||||
displayName: '禁用引号缩进',
|
||||
defaultValue: true,
|
||||
},
|
||||
onOrnament: {
|
||||
displayName: '覆盖装扮字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
onFansMedal: {
|
||||
displayName: '覆盖粉丝勋章字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
onDanmaku: {
|
||||
displayName: '覆盖弹幕字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
onIconFont: {
|
||||
displayName: '覆盖图标字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
onColumn: {
|
||||
displayName: '覆盖专栏自定义字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
onScore: {
|
||||
displayName: '覆盖评分字体',
|
||||
defaultValue: false,
|
||||
},
|
||||
}
|
||||
|
||||
const extraOptions = () => import('./extra-options/entry.vue').then(m => m.default)
|
||||
|
||||
const instantStyles = [
|
||||
{
|
||||
name: `${name}--style--setFontFamily`,
|
||||
style: () => import('./set-font-family.scss'),
|
||||
important: true,
|
||||
},
|
||||
{
|
||||
name: `${name}--style--disableQuotationMarkTextIndent`,
|
||||
style: () => import('./disable-quotation-mark-text-indent.scss'),
|
||||
important: true,
|
||||
},
|
||||
]
|
||||
|
||||
const author = {
|
||||
name: 'Tinhone',
|
||||
link: 'https://github.com/Tinhone',
|
||||
}
|
||||
|
||||
export const component = defineComponentMetadata({
|
||||
name,
|
||||
displayName,
|
||||
description,
|
||||
tags,
|
||||
entry,
|
||||
options,
|
||||
extraOptions,
|
||||
instantStyles,
|
||||
author,
|
||||
})
|
||||
@ -0,0 +1,115 @@
|
||||
$name: 'custom-font-family';
|
||||
$fontFamilyCss: var(--#{$name}--options--font-family) !important;
|
||||
|
||||
// 收集 CSS 路径为单一字符串
|
||||
@function collectPaths($pathList) {
|
||||
$stringPath: '';
|
||||
@each $path in $pathList {
|
||||
$i: index($pathList, $path);
|
||||
@if $i!=1 {
|
||||
$stringPath: '#{$stringPath}, ';
|
||||
}
|
||||
$stringPath: '#{$stringPath}#{$path}';
|
||||
}
|
||||
@return $stringPath;
|
||||
}
|
||||
|
||||
@function getOrnamentPath() {
|
||||
$newVideo: '.reply-item .root-reply-container .content-warp .reply-decorate .user-sailing .user-sailing-text .sailing-text';
|
||||
$dynamic: '.bili-dyn-ornament__type--3 span';
|
||||
$dynamicCommentArea: '.bb-comment .sailing .sailing-info, .comment-bilibili-fold .sailing .sailing-info';
|
||||
@return collectPaths(($newVideo, $dynamic, $dynamicCommentArea));
|
||||
}
|
||||
|
||||
@function getFansMedalPath() {
|
||||
$newVideo: '.badge-level';
|
||||
@return collectPaths(($newVideo));
|
||||
}
|
||||
|
||||
@function getDanmakuPath() {
|
||||
$main: '.bili-dm';
|
||||
@return collectPaths(($main));
|
||||
}
|
||||
|
||||
@function getIconFontPath() {
|
||||
$mainA: '.iconfont';
|
||||
$mainB: '.icon-font';
|
||||
$note: '.read-icon';
|
||||
$noteEdit: '.bili-note-iconfont';
|
||||
$footer: '.bili-footer-font';
|
||||
$bangumiInfo: '[class^="icon-"]';
|
||||
$history: '.bilifont';
|
||||
$message: '.bp-icon-font';
|
||||
$creativeCenterA: '.bcc-iconfont';
|
||||
$creativeCenterB: '.fontvt';
|
||||
@return collectPaths(
|
||||
(
|
||||
$mainA,
|
||||
$mainB,
|
||||
$note,
|
||||
$noteEdit,
|
||||
$footer,
|
||||
$bangumiInfo,
|
||||
$history,
|
||||
$message,
|
||||
$creativeCenterA,
|
||||
$creativeCenterB
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@function getColumnPath() {
|
||||
$mainA: '.article-detail .article-container .article-container__content .article-content .read-article-holder';
|
||||
$mainB: '.article-detail .article-container .article-container__content .article-content .read-article-holder *';
|
||||
@return collectPaths(($mainA, $mainB));
|
||||
}
|
||||
|
||||
@function getScorePath() {
|
||||
$documentary: '.season-cover .score';
|
||||
$big: '.season-cover .season-cover-score';
|
||||
@return collectPaths(($documentary, $big));
|
||||
}
|
||||
|
||||
// 装扮,在评论区、动态等界面显示
|
||||
$ornament: getOrnamentPath();
|
||||
|
||||
// 粉丝勋章,在评论区界面显示
|
||||
$fansMedal: getFansMedalPath();
|
||||
|
||||
// 弹幕,在播放器里显示
|
||||
$danmaku: getDanmakuPath();
|
||||
|
||||
// 图标字体
|
||||
$iconFont: getIconFontPath();
|
||||
|
||||
// 专栏阅读页可能出现的部分自定义字体
|
||||
$column: getColumnPath();
|
||||
|
||||
// 分数,在部分剧集的右下角显示
|
||||
$score: getScorePath();
|
||||
|
||||
// 收集所有路径
|
||||
$discardPaths: collectPaths(($ornament, $fansMedal, $danmaku, $iconFont, $column, $score));
|
||||
|
||||
$onOptionNames: (
|
||||
'on-ornament',
|
||||
'on-fans-medal',
|
||||
'on-danmaku',
|
||||
'on-icon-font',
|
||||
'on-column',
|
||||
'on-score'
|
||||
);
|
||||
$onOptionPathLists: ($ornament, $fansMedal, $danmaku, $iconFont, $column, $score);
|
||||
$onOptionGroups: zip($onOptionNames, $onOptionPathLists);
|
||||
|
||||
html[#{$name}--detect--is-input-empty='false'] {
|
||||
:not(#{$discardPaths}) {
|
||||
font-family: $fontFamilyCss;
|
||||
}
|
||||
|
||||
@each $onOptionName, $onOptionPathList in $onOptionGroups {
|
||||
&[#{$name}--options--#{$onOptionName}='true'] :is(#{$onOptionPathList}) {
|
||||
font-family: $fontFamilyCss;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,7 +31,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { VideoCard } from '@/components/feeds/video-card'
|
||||
import { formatDuration, formatCount, parseDuration } from '@/core/utils/formatters'
|
||||
import { formatDuration, formatCount, parseDuration, parseCount } from '@/core/utils/formatters'
|
||||
import { isNewID } from '@/components/feeds/notify'
|
||||
import { feedsCardTypes, groupVideoFeeds } from '@/components/feeds/api'
|
||||
import VideoCardComponent from '@/components/feeds/VideoCard.vue'
|
||||
@ -98,7 +98,7 @@ export default Vue.extend({
|
||||
upName: author.name,
|
||||
upID: author.mid,
|
||||
watchlater: true,
|
||||
playCount: formatCount(archive.stat.play),
|
||||
playCount: formatCount(parseCount(archive.stat.play)),
|
||||
get new() {
|
||||
return isNewID(this.id)
|
||||
},
|
||||
|
||||
@ -769,3 +769,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#{contains('live-info-content')} {
|
||||
background: transparent !important;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
import { addComponentListener } from '@/core/settings'
|
||||
|
||||
export enum areaPrimaryTitleColorEnum {
|
||||
Dark = '深色',
|
||||
Light = '浅色',
|
||||
}
|
||||
|
||||
const map = {
|
||||
[areaPrimaryTitleColorEnum.Dark]: 'dark',
|
||||
[areaPrimaryTitleColorEnum.Light]: 'light',
|
||||
}
|
||||
|
||||
addComponentListener(
|
||||
'freshHome.areaPrimaryTitleColor',
|
||||
(value: areaPrimaryTitleColorEnum) => {
|
||||
document.documentElement.setAttribute(
|
||||
'fresh-home--options--area-primary-title-color',
|
||||
map[value],
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
@ -97,8 +97,17 @@ export default Vue.extend({
|
||||
bottom: 8px;
|
||||
font-size: 18px;
|
||||
@include semi-bold();
|
||||
transition: color 0.2s ease-out, text-shadow 0.2s ease-out;
|
||||
|
||||
html[fresh-home--options--area-primary-title-color='dark'] & {
|
||||
color: black;
|
||||
}
|
||||
|
||||
html[fresh-home--options--area-primary-title-color='light'] & {
|
||||
color: #fafafa;
|
||||
text-shadow: rgba(0, 0, 0, 0.2) 0 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-other {
|
||||
flex: 1;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { defineOptionsMetadata } from '@/components/define'
|
||||
import { getNumberValidator } from '@/core/utils'
|
||||
import type { FreshLayoutItemSettings } from './layouts/fresh-layout-item'
|
||||
import { areaPrimaryTitleColorEnum } from './init-dropdown-options/area-primary-title-color'
|
||||
|
||||
export enum RankListMode {
|
||||
Default = 'default',
|
||||
@ -48,6 +49,11 @@ export const freshHomeOptionsMetadata = defineOptionsMetadata({
|
||||
displayName: '启用横向滚动',
|
||||
defaultValue: false,
|
||||
},
|
||||
areaPrimaryTitleColor: {
|
||||
displayName: '栏目主标题颜色',
|
||||
dropdownEnum: areaPrimaryTitleColorEnum,
|
||||
defaultValue: areaPrimaryTitleColorEnum.Dark,
|
||||
},
|
||||
maxWidth: {
|
||||
displayName: '最大宽度 (px)',
|
||||
defaultValue: 1440,
|
||||
|
||||
@ -25,6 +25,7 @@ $prefix: 'simplifyLiveroom-switch';
|
||||
&-enterPrompt .chat-history-panel .brush-prompt,
|
||||
&-enterPrompt .chat-item.convention-msg,
|
||||
&-pk .chaos-pk,
|
||||
&-pk .awesome-pk-box,
|
||||
&-topRank .chat-item.top3-notice,
|
||||
&-topRank .chat-item .rank-icon {
|
||||
display: none !important;
|
||||
|
||||
@ -11,9 +11,11 @@ import {
|
||||
DownloadVideoInputItem,
|
||||
} from '../types'
|
||||
import { bangumiApi, videoApi } from './url'
|
||||
import { Options } from '..'
|
||||
import { getComponentSettings } from '@/core/settings'
|
||||
|
||||
/** dash 格式更明确的扩展名 */
|
||||
export const DashExtensions = {
|
||||
export const DefaultDashExtensions = {
|
||||
video: '.mp4',
|
||||
audio: '.m4a',
|
||||
flacAudio: '.flac',
|
||||
@ -27,7 +29,7 @@ export enum DashCodec {
|
||||
Av1 = 'AV1',
|
||||
}
|
||||
export interface Dash {
|
||||
type: keyof typeof DashExtensions
|
||||
type: keyof typeof DefaultDashExtensions
|
||||
bandWidth: number
|
||||
codecs: string
|
||||
codecId: number
|
||||
@ -50,12 +52,25 @@ export interface DashFilters {
|
||||
video?: (dash: VideoDash) => boolean
|
||||
audio?: (dash: AudioDash) => boolean
|
||||
}
|
||||
const getDashExtensions = (type: keyof typeof DefaultDashExtensions): string => {
|
||||
const { options } = getComponentSettings<Options>('downloadVideo')
|
||||
if (type === 'video') {
|
||||
return options.dashVideoExtension
|
||||
}
|
||||
if (type === 'audio') {
|
||||
return options.dashAudioExtension
|
||||
}
|
||||
if (type === 'flacAudio') {
|
||||
return options.dashFlacAudioExtension
|
||||
}
|
||||
return DefaultDashExtensions[type] ?? DashFragmentExtension
|
||||
}
|
||||
const dashToFragment = (dash: Dash): DownloadVideoFragment => ({
|
||||
url: dash.downloadUrl,
|
||||
backupUrls: dash.backupUrls,
|
||||
length: dash.duration,
|
||||
size: Math.trunc((dash.bandWidth * dash.duration) / 8),
|
||||
extension: DashExtensions[dash.type] ?? DashFragmentExtension,
|
||||
extension: getDashExtensions(dash.type),
|
||||
})
|
||||
export const dashToFragments = (info: {
|
||||
videoDashes: VideoDash[]
|
||||
|
||||
@ -1,6 +1,31 @@
|
||||
import { defineComponentMetadata } from '@/components/define'
|
||||
import {
|
||||
OptionsOfMetadata,
|
||||
defineComponentMetadata,
|
||||
defineOptionsMetadata,
|
||||
} from '@/components/define'
|
||||
import { hasVideo } from '@/core/spin-query'
|
||||
import { DefaultDashExtensions } from './apis/dash'
|
||||
|
||||
const options = defineOptionsMetadata({
|
||||
basicConfig: {
|
||||
defaultValue: {},
|
||||
displayName: '基础配置',
|
||||
hidden: true,
|
||||
},
|
||||
dashVideoExtension: {
|
||||
defaultValue: DefaultDashExtensions.video,
|
||||
displayName: 'DASH 视频扩展名',
|
||||
},
|
||||
dashAudioExtension: {
|
||||
defaultValue: DefaultDashExtensions.audio,
|
||||
displayName: 'DASH 普通音频扩展名',
|
||||
},
|
||||
dashFlacAudioExtension: {
|
||||
defaultValue: DefaultDashExtensions.flacAudio,
|
||||
displayName: 'DASH FLAC 音频扩展名',
|
||||
},
|
||||
})
|
||||
export type Options = OptionsOfMetadata<typeof options>
|
||||
export const component = defineComponentMetadata({
|
||||
name: 'downloadVideo',
|
||||
displayName: '下载视频',
|
||||
@ -12,12 +37,6 @@ export const component = defineComponentMetadata({
|
||||
condition: () => hasVideo(),
|
||||
},
|
||||
tags: [componentsTags.video],
|
||||
options: {
|
||||
basicConfig: {
|
||||
defaultValue: {},
|
||||
displayName: '基础配置',
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
options,
|
||||
// plugin,
|
||||
})
|
||||
|
||||
@ -37,6 +37,7 @@ export const component = defineComponentMetadata({
|
||||
}
|
||||
Promise.race([
|
||||
select('.multi-page-v1 .head-left h3'),
|
||||
select('.video-sections-v1 .first-line-title'),
|
||||
select('.base-video-sections-v1 .first-line-title'),
|
||||
]).then(titleElement => {
|
||||
if (!titleElement) {
|
||||
|
||||
@ -5,9 +5,12 @@ import { allVideoUrls } from '@/core/utils/urls'
|
||||
let cancel: () => void
|
||||
export const disableScrollVolume = () => {
|
||||
return preventEvent(unsafeWindow, 'mousewheel', () => {
|
||||
const isFullscreen = ['player-mode-full', 'player-fullscreen-fix', 'player-full-win'].some(
|
||||
token => document.body.classList.contains(token),
|
||||
)
|
||||
const isFullscreen = [
|
||||
'player-mode-full',
|
||||
'player-mode-web',
|
||||
'player-fullscreen-fix',
|
||||
'player-full-win',
|
||||
].some(token => document.body.classList.contains(token))
|
||||
return isFullscreen
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.8.4",
|
||||
"version": "2.8.5",
|
||||
"author": "Grant Howard, Coulomb-G",
|
||||
"copyright": "[year], Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)",
|
||||
"license": "MIT",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { getUID, pascalCase } from '@/core/utils'
|
||||
import { getJsonWithCredentials } from '@/core/ajax'
|
||||
import { formatCount, formatDuration, parseDuration } from '@/core/utils/formatters'
|
||||
import { formatCount, formatDuration, parseCount, parseDuration } from '@/core/utils/formatters'
|
||||
import { watchlaterList } from '@/components/video/watchlater'
|
||||
import { getData, registerData } from '@/plugins/data'
|
||||
import { descendingStringSort } from '@/core/utils/sort'
|
||||
@ -140,8 +140,8 @@ export const getVideoFeeds = withContentFilter(
|
||||
like: formatCount(stat.like.count),
|
||||
duration: parseDuration(archive.duration_text),
|
||||
durationText: formatDuration(parseDuration(archive.duration_text)),
|
||||
playCount: formatCount(archive.stat.play),
|
||||
danmakuCount: formatCount(archive.stat.danmaku),
|
||||
playCount: formatCount(parseCount(archive.stat.play)),
|
||||
danmakuCount: formatCount(parseCount(archive.stat.danmaku)),
|
||||
watchlater: watchlaterList.includes(archive.aid),
|
||||
}
|
||||
}),
|
||||
@ -164,8 +164,8 @@ export const getVideoFeeds = withContentFilter(
|
||||
time: new Date(author.pub_ts * 1000),
|
||||
like: formatCount(stat.like.count),
|
||||
durationText: '',
|
||||
playCount: formatCount(pgc.stat.play),
|
||||
danmakuCount: formatCount(pgc.stat.danmaku),
|
||||
playCount: formatCount(parseCount(pgc.stat.play)),
|
||||
danmakuCount: formatCount(parseCount(pgc.stat.danmaku)),
|
||||
watchlater: false,
|
||||
}
|
||||
})
|
||||
|
||||
@ -48,11 +48,16 @@ const getText = (dynamicModule: any, cardType: FeedsCardType) => {
|
||||
return text
|
||||
}
|
||||
const { desc: mainDesc, major } = dynamicModule
|
||||
const mainText = mainDesc?.text ?? ''
|
||||
let typeText = ''
|
||||
const mainText = (() => {
|
||||
if (major?.opus) {
|
||||
return lodash.get(major.opus, 'summary.text')
|
||||
}
|
||||
return mainDesc?.text ?? ''
|
||||
})()
|
||||
const typeText = (() => {
|
||||
switch (cardType) {
|
||||
default: {
|
||||
break
|
||||
return ''
|
||||
}
|
||||
case feedsCardTypes.bangumi:
|
||||
case feedsCardTypes.column:
|
||||
@ -60,14 +65,16 @@ const getText = (dynamicModule: any, cardType: FeedsCardType) => {
|
||||
const target = major.archive ?? major.pgc ?? major.article
|
||||
if (target) {
|
||||
const { title, desc } = target
|
||||
typeText = combineText(title, desc)
|
||||
} else if (major.opus) {
|
||||
return combineText(title, desc)
|
||||
}
|
||||
if (major.opus) {
|
||||
const { title, summary } = major.opus
|
||||
typeText = combineText(title, summary.text)
|
||||
return combineText(title, summary.text)
|
||||
}
|
||||
break
|
||||
return ''
|
||||
}
|
||||
}
|
||||
})()
|
||||
return combineText(mainText, typeText)
|
||||
}
|
||||
const parseCard = async (element: HTMLElement): Promise<FeedsCard> => {
|
||||
|
||||
@ -51,6 +51,21 @@ export const formatDuration = (time: number, fixed = 0) => {
|
||||
}
|
||||
return `${hour}:${minute.padStart(2, '0')}:${second.padStart(secondTotalLength, '0')}`
|
||||
}
|
||||
export const parseCount = (countText: string | number) => {
|
||||
if (typeof countText === 'number') {
|
||||
return countText
|
||||
}
|
||||
const unit = (() => {
|
||||
if (countText.match(/亿$/)) {
|
||||
return 1e8
|
||||
}
|
||||
if (countText.match(/万$/)) {
|
||||
return 1e4
|
||||
}
|
||||
return 1
|
||||
})()
|
||||
return parseFloat(countText) * unit
|
||||
}
|
||||
const formatCountData = (count: number | string) => {
|
||||
if (typeof count === 'string') {
|
||||
count = parseInt(count)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user