From c632150734e83a8c531fd71ee2210d4657071fcb Mon Sep 17 00:00:00 2001 From: Akari <60416767+MotooriKashin@users.noreply.github.com> Date: Sat, 3 Aug 2024 19:12:38 +0800 Subject: [PATCH] bump 1.0.3.0 (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 主页显示视频浮窗 * 添加主页番剧浮动信息 * 添加首页导航栏 --- dist/manifest.json | 2 +- scripts/arbitrary-extensions.mjs | 1 - src/main/bilibili/comment/card.ts | 2 +- src/main/bilibili/comment/style/comment.css | 2 +- src/main/bilibili/home/index.ts | 110 ++++++++++++++++- src/main/bilibili/home/ranking.ts | 2 +- src/main/bilibili/home/style/index.css | 55 +++++++++ src/main/bilibili/home/style/video-info.css | 107 ++++++++++++++++ .../bilibili/home/style/video-info.d.css.ts | 2 + src/main/bilibili/home/timeline.ts | 2 +- src/main/bilibili/home/video-info.ts | 116 ++++++++++++++++++ 11 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 src/main/bilibili/home/style/video-info.css create mode 100644 src/main/bilibili/home/style/video-info.d.css.ts create mode 100644 src/main/bilibili/home/video-info.ts diff --git a/dist/manifest.json b/dist/manifest.json index 5be5175..f1a607d 100644 --- a/dist/manifest.json +++ b/dist/manifest.json @@ -80,5 +80,5 @@ "declarativeNetRequest", "declarativeNetRequestWithHostAccess" ], - "version": "1.0.2.0" + "version": "1.0.3.0" } \ No newline at end of file diff --git a/scripts/arbitrary-extensions.mjs b/scripts/arbitrary-extensions.mjs index bb51f91..06908ef 100644 --- a/scripts/arbitrary-extensions.mjs +++ b/scripts/arbitrary-extensions.mjs @@ -6,7 +6,6 @@ import fs from 'fs/promises'; /** 非代码文件所在路径 */ const paths = [ 'src/player/assets/svg', - 'src/main/bilibili/comment/style', ]; for (const path of paths) { diff --git a/src/main/bilibili/comment/card.ts b/src/main/bilibili/comment/card.ts index 1a2f76f..7fbbde4 100644 --- a/src/main/bilibili/comment/card.ts +++ b/src/main/bilibili/comment/card.ts @@ -117,7 +117,7 @@ export class IdCard extends HTMLElement { if (target && !this.contains(target)) { const node = (target)?.closest('[data-mid]'); if (node) { - const mid = node.dataset.mid; + const { mid } = node.dataset; if (mid) { const id = crypto.randomUUID(); node.style.setProperty('anchor-name', `--${id}`); diff --git a/src/main/bilibili/comment/style/comment.css b/src/main/bilibili/comment/style/comment.css index f88ded0..9494d9e 100644 --- a/src/main/bilibili/comment/style/comment.css +++ b/src/main/bilibili/comment/style/comment.css @@ -32,7 +32,7 @@ inline-size: 20px; block-size: 20px; inset-inline-end: 0; - inset-block-start: 0; + inset-block-end: 0; background-image: url(//s1.hdslb.com/bfs/static/jinkela/videoplay/asserts/user-auth.png); background-repeat: no-repeat; z-index: 3; diff --git a/src/main/bilibili/home/index.ts b/src/main/bilibili/home/index.ts index 0858cc6..fb07c24 100644 --- a/src/main/bilibili/home/index.ts +++ b/src/main/bilibili/home/index.ts @@ -16,6 +16,7 @@ import { Format } from "../../../utils/fomat"; import { https } from "../../../utils/https"; import { Ranking } from "./ranking"; import { Timeline } from "./timeline"; +import { VideoInfo } from "./video-info"; /** 顶栏 */ @customElement('div') @@ -39,10 +40,14 @@ export class Home extends HTMLDivElement { // #inited = false; /** 每当元素添加到文档中时调用。 */ - // connectedCallback() {} + connectedCallback() { + document.body.appendChild(this.$form); + } /** 每当元素从文档中移除时调用。 */ - // disconnectedCallback() {} + disconnectedCallback() { + this.$form.remove(); + } /** 每当元素被移动到新文档中时调用。 */ // adoptedCallback() {} @@ -113,6 +118,8 @@ export class Home extends HTMLDivElement { private $bili_documentary = this.appendChild(new Ranking('纪录片', '/documentary', REGION.DOCUMENTARY)); + private $form = Element.add('form', { class: 'nav-form' }) + constructor() { super(); this.insertAdjacentHTML('beforeend', ``); @@ -138,6 +145,26 @@ export class Home extends HTMLDivElement { this.$bili_documentary.classList.add('bili-documentary'); this.$timeline_bangumi.classList.add('timeline-bangumi'); this.$timeline_guochuang.classList.add('timeline-guochuang'); + this.$form.insertAdjacentHTML('afterbegin', ` + + + + + + + + + + + + + + + + +`) + + new VideoInfo(); locs(4694, 34).then(d => { // 主推荐滚动图 @@ -228,6 +255,85 @@ export class Home extends HTMLDivElement { }); } }); + this.$form.addEventListener('change', () => { + const d = new FormData(this.$form); + const i = +[...d.values()][0]; + switch (i) { + case 0: { + this.$bili_live.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 1: { + this.$bili_douga.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 2: { + this.$timeline_bangumi.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 3: { + this.$timeline_guochuang.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 4: { + this.$bili_music.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 5: { + this.$bili_dance.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 6: { + this.$bili_game.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 7: { + this.$bili_knowledge.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 8: { + this.$bili_technology.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 9: { + this.$bili_life.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 10: { + this.$bili_kichiku.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 11: { + this.$bili_fashion.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 12: { + this.$bili_news.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 13: { + this.$bili_ent.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 14: { + this.$bili_movie.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 15: { + this.$bili_tv.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 16: { + this.$bili_cinephile.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + case 17: { + this.$bili_documentary.scrollIntoView({ behavior: 'smooth', block: 'center' }); + break; + } + } + }); + this.carouselPointerLeave(); } diff --git a/src/main/bilibili/home/ranking.ts b/src/main/bilibili/home/ranking.ts index 8ddc447..8f1143c 100644 --- a/src/main/bilibili/home/ranking.ts +++ b/src/main/bilibili/home/ranking.ts @@ -102,7 +102,7 @@ export class Ranking extends HTMLDivElement { private rankRegion() { rankingRegion(this.rid).then(d => { - d && ((this.$rCon.childNodes[1]).innerHTML = AV.fromStr(https(d.map((d, i) => `
${i + 1}
${i ? '' : ``}${d.title}${i ? '' : `
`}
`).join('')))); + d && ((this.$rCon.childNodes[1]).innerHTML = AV.fromStr(https(d.map((d, i) => `
${i + 1}
${i ? '' : ``}${d.title}${i ? '' : `
`}
`).join('')))); }) } } \ No newline at end of file diff --git a/src/main/bilibili/home/style/index.css b/src/main/bilibili/home/style/index.css index d593bb4..64d2970 100644 --- a/src/main/bilibili/home/style/index.css +++ b/src/main/bilibili/home/style/index.css @@ -710,4 +710,59 @@ .timeline-guochuang>.l-con .icon-promote { background-position: -140px -1611px; +} + +.nav-form { + position: fixed; + inset-inline-end: calc((100vi - 980px) / 2); + inset-block-start: 50%; + padding-block-start: 6px; + font-size: 12px; + background-color: #f6f9fa; + border: 1px solid #e5e9ef; + overflow: hidden; + border-radius: 4px; + border-start-end-radius: 4px; + border-start-start-radius: 4px; + translate: 150% -50%; + display: flex; + flex-direction: column; + + @media screen and (min-width:1400px) { + + & { + inset-inline-end: calc((100vi - 1160px) / 2); + } + } + + @media screen and (min-width:2500px) { + + & { + inset-inline-end: calc((100vi - 1920px) / 2); + } + } + + >label { + block-size: 24px; + display: flex; + justify-content: center; + align-items: center; + transition: background-color .3s, color .3s; + cursor: pointer; + user-select: none; + + >input { + appearance: none; + } + + &:hover, + &:has(input:checked) { + background-color: #00a1d6; + color: #fff; + } + + &:has(input:checked) { + pointer-events: none; + } + } } \ No newline at end of file diff --git a/src/main/bilibili/home/style/video-info.css b/src/main/bilibili/home/style/video-info.css new file mode 100644 index 0000000..25196da --- /dev/null +++ b/src/main/bilibili/home/style/video-info.css @@ -0,0 +1,107 @@ +@scope { + :scope { + inset-area: block-start; + inline-size: 320px; + border: 1px solid #ccd0d7; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, .16); + box-sizing: border-box; + overflow: hidden; + background-color: #fff; + padding: 12px; + font-size: 12px; + row-gap: .75em; + margin: 0; + + &:popover-open, + &:hover { + display: flex; + flex-direction: column; + } + } +} + +.v-title { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + &:empty { + display: none; + } +} + +.v-info { + color: #99a2aa; + display: flex; + column-gap: 10px; + + &:empty { + display: none; + } +} + +.v-preview { + padding-block: 8px; + padding-block-end: 12px; + border-block-end: 1px solid #e5e9ef; + display: flex; + column-gap: 8px; + + >img { + block-size: 63px; + } + + >p { + margin: 0; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + text-overflow: ellipsis; + color: #99a2aa; + line-height: 21px; + } +} + +.v-data { + display: flex; + column-gap: 2em; + + >span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: #99a2aa; + display: flex; + align-items: center; + column-gap: 4px; + + >i { + display: inline-block; + inline-size: 12px; + block-size: 12px; + background-image: url(//static.hdslb.com/images/base/icons.png); + } + + &.play>i { + background-position: -282px -90px; + } + + &.danmu>i { + background-position: -282px -218px; + } + + &.star>i { + background-position: -282px -346px; + } + + &.coin>i { + background-position: -282px -410px; + } + + &.play>i { + background-position: -282px -90px; + } + } +} \ No newline at end of file diff --git a/src/main/bilibili/home/style/video-info.d.css.ts b/src/main/bilibili/home/style/video-info.d.css.ts new file mode 100644 index 0000000..3e963d8 --- /dev/null +++ b/src/main/bilibili/home/style/video-info.d.css.ts @@ -0,0 +1,2 @@ +declare const css_video_info: string; +export default css_video_info; \ No newline at end of file diff --git a/src/main/bilibili/home/timeline.ts b/src/main/bilibili/home/timeline.ts index 495bc72..1a84dd2 100644 --- a/src/main/bilibili/home/timeline.ts +++ b/src/main/bilibili/home/timeline.ts @@ -97,7 +97,7 @@ export class Timeline extends HTMLDivElement { }); list(type).then(d => { - (this.$rCon.childNodes[1]).innerHTML = AV.fromStr(https(d.map((d, i) => ``).join(''))) + (this.$rCon.childNodes[1]).innerHTML = AV.fromStr(https(d.map((d, i) => ``).join(''))) }) } diff --git a/src/main/bilibili/home/video-info.ts b/src/main/bilibili/home/video-info.ts new file mode 100644 index 0000000..cbb697c --- /dev/null +++ b/src/main/bilibili/home/video-info.ts @@ -0,0 +1,116 @@ +import { pgcAppSeason } from "../../../io/com/bilibili/api/pgc/view/v2/app/season"; +import { cards } from "../../../io/com/bilibili/api/x/article/cards"; +import { customElement } from "../../../utils/Decorator/customElement"; +import { Element } from "../../../utils/element"; +import { Format } from "../../../utils/fomat"; +import { https } from "../../../utils/https"; +import { TOTP } from "../../../utils/TOTP"; +import css_video_info from "./style/video-info.css"; + +@customElement(undefined, `video-info-${TOTP.now()}`) +export class VideoInfo extends HTMLElement { + + /** + * 需要监听变动的属性。 + * 与实例方法`attributeChangedCallback`配合使用。 + * 此字符串序列定义了`attributeChangedCallback`回调时的第一个参数的可能值。 + */ + // static observedAttributes = []; + + /** + * 在属性更改、添加、移除或替换时调用。 + * 需要与静态属性`observedAttributes`配合使用。 + * 此回调的第一个参数在`observedAttributes`数组中定义。 + */ + // attributeChangedCallback(name: IobservedAttributes, oldValue: string, newValue: string) {} + + /** 初始化标记 */ + // #inited = false; + + /** 每当元素添加到文档中时调用。 */ + // connectedCallback() { } + + /** 每当元素从文档中移除时调用。 */ + // disconnectedCallback() { } + + /** 每当元素被移动到新文档中时调用。 */ + // adoptedCallback() {} + + #host = this.attachShadow({ mode: 'closed' }); + + private $title = this.#host.appendChild(Element.add('div', { class: 'v-title' })); + + private $info = this.#host.appendChild(Element.add('div', { class: 'v-info' })); + + private $preview = this.#host.appendChild(Element.add('div', { class: 'v-preview' })); + + private $data = this.#host.appendChild(Element.add('div', { class: 'v-data' })); + + constructor() { + super(); + this.$title.insertAdjacentHTML('beforebegin', ``); + this.popover = 'auto'; + + document.addEventListener('pointerover', this.onPointerover); + } + + private onPointerover = ({ target }: PointerEvent) => { + const node = (target)?.closest('[data-v-aid]'); + if (node) { + const { vAid } = node.dataset; + if (vAid) { + const id = crypto.randomUUID(); + node.style.setProperty('anchor-name', `--${id}`); + this.style.setProperty('position-anchor', `--${id}`); + this.onMouseoverAid(vAid); + } + } else { + const node = (target)?.closest('[data-v-ssid]'); + if (node) { + const { vSsid } = node.dataset; + if (vSsid) { + const id = crypto.randomUUID(); + node.style.setProperty('anchor-name', `--${id}`); + this.style.setProperty('position-anchor', `--${id}`); + this.onMouseoverSsid(vSsid); + } + } else { + this.hidePopover(); + } + } + } + + private onMouseoverAid = ( + aid: string | number, + ) => { + cards({ av: aid }).then(d => { + const card = d[`av${aid}`]; + if (card) { + this.$title.innerText = card.title; + this.$info.innerHTML = `${card.owner.name}${Format.eTime(card.pubdate)}`; + this.$preview.innerHTML = https(`

${card.desc}

`); + this.$data.innerHTML = `${Format.carry(card.stat.view)}${Format.carry(card.stat.danmaku)}${Format.carry(card.stat.favorite)}${Format.carry(card.stat.coin)}`; + this.showPopover(); + } + }) + } + + private onMouseoverSsid = ( + ssid: string | number, + ) => { + pgcAppSeason({ season_id: ssid }).then(d => { + if (d) { + this.$title.innerHTML = d.title; + this.$info.innerHTML = `${d.type_desc}`; + this.$preview.innerHTML = https(`

${d.evaluate}

`); + this.$data.innerHTML = `${Format.carry(d.stat.views)}${Format.carry(d.stat.danmakus)}${Format.carry(d.stat.favorites)}${Format.carry(d.stat.coins)}`; + this.showPopover(); + } + }) + } + + showPopover() { + document.body.contains(this) || document.body.appendChild(this); + super.showPopover(); + } +} \ No newline at end of file