Skip to content

Commit

Permalink
optimized superchat feature and fixed only vtuber mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
eric2788 committed Mar 10, 2024
1 parent 80feab2 commit 66cf4ef
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 25 deletions.
6 changes: 2 additions & 4 deletions src/api/bilibili.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function getStreamInfo(room: string): Promise<StreamInfo> {
title: data.room_info.title,
uid: data.room_info.uid.toString(),
username: data.anchor_info.base_info.uname,
isVtuber: data.room_info.parent_area_id !== 9, // 分區辨識
isVtuber: data.room_info.parent_area_id === 9, // 分區辨識
status: data.room_info.live_status === 1 ? 'online' : 'offline',
liveTime: data.room_info.live_start_time,
isTheme: isThemePage() // 目前尚未知道如何在 API 中取得
Expand Down Expand Up @@ -62,9 +62,7 @@ export async function ensureLogin(): Promise<boolean> {

export async function ensureIsVtuber(info: StreamInfo): Promise<StreamInfo> {
// real vtuber identification
const vup = await retryCatcher(() => identifyVup(info.uid), 3,
{ id: info.uid, name: info.username, locale: 'idk' } // if failed, always return is vtuber = true
)
const vup = await retryCatcher(() => identifyVup(info.uid), 3) // if failed, use area id to identify

// if not undefined
if (vup) {
Expand Down
2 changes: 1 addition & 1 deletion src/contents/index/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const getStreamInfoFallbacks = [
title: r.data.room_info.title,
uid: r.data.room_info.uid.toString(),
username: r.data.anchor_info.base_info.uname,
isVtuber: r.data.room_info.parent_area_id !== 9, // 分區辨識
isVtuber: r.data.room_info.parent_area_id === 9, // 分區辨識
status: r.data.room_info.live_status === 1 ? 'online' : 'offline',
liveTime: r.data.room_info.live_start_time
}) as StreamInfo),
Expand Down
9 changes: 9 additions & 0 deletions src/features/superchat/components/SuperChatCaptureLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import SuperChatArea from "./SuperChatArea"
import SuperChatFloatingButton from "./SuperChatFloatingButton"
import type { SuperChatCard } from "./SuperChatItem"
import { useTransaction } from "~hooks/optimizer"
import { useWebScreenChange } from "~hooks/bilibili"
import SuperChatFeatureContext from "~contexts/SuperChatFeatureContext"

export type SuperChatCaptureLayerProps = {
offlineRecords: SuperChatCard[]
Expand All @@ -17,6 +19,7 @@ export type SuperChatCaptureLayerProps = {
function SuperChatCaptureLayer(props: SuperChatCaptureLayerProps): JSX.Element {

const { settings, info } = useContext(ContentContext)
const { displayFullScreen } = useContext(SuperChatFeatureContext)
const { offlineRecords } = props
const {
enabledRecording,
Expand Down Expand Up @@ -60,6 +63,12 @@ function SuperChatCaptureLayer(props: SuperChatCaptureLayerProps): JSX.Element {
push(superChatProps)
})

const screenStatus = useWebScreenChange(settings['settings.developer'].classes)

if (screenStatus !== 'normal' && !displayFullScreen) {
return <></>
}

return (
<SuperChatFloatingButton>
<SuperChatArea
Expand Down
28 changes: 21 additions & 7 deletions src/settings/features/superchat/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Switch, Typography } from "@material-tailwind/react"
import { type ChangeEvent } from "react"
import type { StateProxy } from "~hooks/binding"
import ColorInput from "~settings/components/ColorInput"
import type { HexColor } from "~types/common"
import type { FeatureSettingsDefinition } from ".."
import { Fragment, type ChangeEvent } from "react"
import ColorInput from "~settings/components/ColorInput"
import type { StateProxy } from "~hooks/binding"

export const title: string = '醒目留言'

Expand All @@ -13,22 +14,35 @@ export const define: FeatureSettingsDefinition = {
export type FeatureSettingSchema = {
floatingButtonColor: HexColor,
buttonColor: HexColor,
displayFullScreen: boolean
}

export const defaultSettings: Readonly<FeatureSettingSchema> = {
floatingButtonColor: '#db7d1f',
buttonColor: '#db7d1f',
displayFullScreen: true
}


function SuperchatFeatureSettings({state, useHandler}: StateProxy<FeatureSettingSchema>): JSX.Element {
function SuperchatFeatureSettings({ state, useHandler }: StateProxy<FeatureSettingSchema>): JSX.Element {

const handler = useHandler<ChangeEvent<HTMLInputElement>, string>((e) => e.target.value)
const str = useHandler<ChangeEvent<HTMLInputElement>, string>((e) => e.target.value)
const bool = useHandler<ChangeEvent<HTMLInputElement>, boolean>((e) => e.target.checked)

return (
<div className="grid max-md:grid-cols-1 md:grid-cols-2 gap-10">
<ColorInput data-testid="floater-color" label="浮动按钮颜色" value={state.floatingButtonColor} onChange={handler('floatingButtonColor')} />
<ColorInput data-testid="operator-color" label="操作按钮颜色" value={state.buttonColor} onChange={handler('buttonColor')} />
<ColorInput data-testid="floater-color" label="浮动按钮颜色" value={state.floatingButtonColor} onChange={str('floatingButtonColor')} />
<ColorInput data-testid="operator-color" label="操作按钮颜色" value={state.buttonColor} onChange={str('buttonColor')} />
<div className="md:col-span-2 max-md:col-span-1">
<Switch
crossOrigin={'annoymous'}
label={
<Typography className="font-medium" >在全屏模式下显示</Typography>
}
checked={state.displayFullScreen}
onChange={bool('displayFullScreen')}
/>
</div>
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/settings/fragments/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const defaultSettings: Readonly<SettingSchema> = {
enabledRecording: [],
common: {
enabledPip: false,
onlyVtuber: false,
onlyVtuber: true,
monitorWindow: false,
useStreamingTime: true
},
Expand Down
28 changes: 26 additions & 2 deletions tests/content.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,30 @@ test('測試全屏時有否根據設定顯示隱藏浮動按鈕', async ({ conte
await expect(button).toBeVisible()
})

test('测试仅限虚拟主播', async ({ context, room, tabUrl, api }) => {

const nonVtbRooms = await api.getLiveRooms(1, 11) // 获取知识分区直播间
test.skip(nonVtbRooms.length === 0, '没有知识分区直播间')

await room.enterToRoom(nonVtbRooms[0])
const content = await room.getContentLocator()

const button = content.getByText('功能菜单')
await expect(button).toBeHidden()

const settingsPage = await context.newPage()
await settingsPage.goto(tabUrl('settings.html'), { waitUntil: 'domcontentloaded' })
await settingsPage.getByText('功能设定').click()
await settingsPage.getByText('仅限虚拟主播').click()
await settingsPage.getByText('保存设定').click()

await room.page.bringToFront()
await content.waitForTimeout(1000)

await expect(button).toBeVisible()

})

test('測試底部的按鈕', async ({ content, context }) => {

const button = content.getByText('功能菜单')
Expand Down Expand Up @@ -240,7 +264,7 @@ test('測試底部的按鈕', async ({ content, context }) => {
await p3.close()
})

test('測試导航', async ({ room, content, serviceWorker }) => {
test('測試导航', async ({ room, content, serviceWorker }) => {

const overlay = content.locator('.react-joyride__overlay')

Expand All @@ -261,7 +285,7 @@ test('測試导航', async ({ room, content, serviceWorker }) => {
const skip = content.getByRole('button', { name: '跳过' })
const finish = content.getByRole('button', { name: '完成' })

while(await next.isVisible()) {
while (await next.isVisible()) {
await next.click()
await content.waitForTimeout(100)
}
Expand Down
27 changes: 27 additions & 0 deletions tests/features/superchat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,33 @@ test('測試房間名單列表(黑名單/白名單)', async ({ room, content, co

})

test('測試全屏時有否根據設定顯示隱藏浮動按鈕', async ({ content, context, tabUrl }) => {

const button = content.locator('button', { hasText: /^$/ })
await expect(button).toBeVisible()

logger.info('正在測試啟用時切換網頁全屏...')
await content.locator('#live-player').dblclick()
await expect(button).toBeVisible()
await content.locator('#live-player').dblclick()

logger.info('正在修改設定...')
const settingsPage = await context.newPage()
await settingsPage.goto(tabUrl('settings.html'), { waitUntil: 'domcontentloaded' })
await settingsPage.getByText('功能设定').click()
await settingsPage.locator('#features\\.superchat').getByText('在全屏模式下显示').click() // closed
await settingsPage.getByText('保存设定').click()
await settingsPage.close()

await expect(button).toBeVisible()

logger.info('正在測試禁用時切換網頁全屏...')
await content.locator('#live-player').dblclick()
await expect(button).toBeHidden()
await content.locator('#live-player').dblclick()

await expect(button).toBeVisible()
})

test('測試保存設定後 css 能否生效', async ({ content, page, tabUrl, context }) => {

Expand Down
1 change: 0 additions & 1 deletion tests/fixtures/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ export const extensionBase = base.extend<ExtensionFixture, ExtensionOptions & Ex
const context = await chromium.launchPersistentContext('', {
headless: false,
args: [
'--mute-audio',
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`,
...(process.env.CI ? ['--headless=new'] : [])
Expand Down
7 changes: 4 additions & 3 deletions tests/helpers/bilibili-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,13 @@ export default class BilbiliApi {

/**
* 获取一页的直播房间。
* @param page - 要获取的页码。
* @param page - 要获取的页码, 默认为 1。
* @param area - 要获取的分区,默认为 9 (虚拟主播分区)。
* @returns 一个解析为直播房间信息数组的Promise。
* @throws 如果无法获取直播房间列表,则抛出错误。
*/
async getLiveRooms(page: number = 1): Promise<LiveRoomInfo[]> {
const data = await this.fetch(`/xlive/web-interface/v1/second/getList?platform=web&parent_area_id=9&area_id=0&sort_type=online&page=${page}`)
async getLiveRooms(page: number = 1, area: number = 9): Promise<LiveRoomInfo[]> {
const data = await this.fetch(`/xlive/web-interface/v1/second/getList?platform=web&parent_area_id=${area}&area_id=0&sort_type=online&page=${page}`)
if (data.code !== 0) throw new Error(`获取bilibili直播房间列表失败:${data.message}`)
return data.data.list as LiveRoomInfo[]
}
Expand Down
2 changes: 1 addition & 1 deletion tests/helpers/room-finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class RoomTypeFinder {
return type
}
}
logger.info(`房间 ${page.info.roomid} 的类型是: 普通`)
logger.info(`房间 ${page.info.roomid} 的类型是: normal`)
return 'normal'
}

Expand Down
10 changes: 5 additions & 5 deletions tests/pages/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test('測試能否保存設定', async ({ settings: page }) => {
await page.getByText('功能设定').click()

const chexkboxVtbOnly = page.getByTestId('vtb-only')
await expect(chexkboxVtbOnly).not.toBeChecked()
await expect(chexkboxVtbOnly).toBeChecked()
await page.getByText('仅限虚拟主播').click()

const checkboxMonitor = page.getByTestId('monitor-window')
Expand Down Expand Up @@ -71,7 +71,7 @@ test('測試能否保存設定', async ({ settings: page }) => {

logger.info('正在验证功能設定....')
await page.getByText('功能设定').click()
await expect(chexkboxVtbOnly).toBeChecked()
await expect(chexkboxVtbOnly).not.toBeChecked()
await expect(checkboxMonitor).toBeChecked()
await expect(inputSubtitleSize).toHaveValue('20')
await expect(inputFirstSubtitleSize).toHaveValue('22')
Expand All @@ -96,7 +96,7 @@ test('測試導出導入設定', async ({ settings: page }) => {
await page.getByText('功能设定').click()

const chexkboxVtbOnly = page.getByTestId('vtb-only')
await expect(chexkboxVtbOnly).not.toBeChecked()
await expect(chexkboxVtbOnly).toBeChecked()
await page.getByText('仅限虚拟主播').click()

const checkboxMonitor = page.getByTestId('monitor-window')
Expand All @@ -120,7 +120,7 @@ test('測試導出導入設定', async ({ settings: page }) => {

logger.info('正在验证功能設定....')
await page.getByText('功能设定').click()
await expect(chexkboxVtbOnly).toBeChecked()
await expect(chexkboxVtbOnly).not.toBeChecked()
await expect(checkboxMonitor).toBeChecked()
await expect(inputSubtitleSize).toHaveValue('20')
await expect(inputFirstSubtitleSize).toHaveValue('22')
Expand All @@ -135,7 +135,7 @@ test('測試導出導入設定', async ({ settings: page }) => {
await page.getByText('设定已经导入成功。').waitFor({ state: 'visible' })

logger.info('正在验证功能設定....')
await expect(chexkboxVtbOnly).not.toBeChecked()
await expect(chexkboxVtbOnly).toBeChecked()
await expect(checkboxMonitor).not.toBeChecked()
await expect(inputSubtitleSize).toHaveValue('16')
await expect(inputFirstSubtitleSize).toHaveValue('18')
Expand Down

0 comments on commit 66cf4ef

Please sign in to comment.