Skip to content

Commit

Permalink
fix: iframe加载video时样式丢失;切换tab导致sc列表定时器不准
Browse files Browse the repository at this point in the history
  • Loading branch information
eeelester committed Dec 27, 2024
1 parent 6f93cbd commit 3df5a89
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 91 deletions.
5 changes: 4 additions & 1 deletion .release-it.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"github": {
"release": true
"release": true,
"assets": [
".output/*.zip"
]
},
"npm": {
"publish": false
Expand Down
23 changes: 22 additions & 1 deletion components/ScList/hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import type { ScInfo } from './type'

type propRef = React.MutableRefObject<HTMLDivElement | undefined | null>

Expand Down Expand Up @@ -55,4 +56,24 @@ function useMove(ref: propRef, scDocument: Document) {
return { ...position }
}

export { useMove }
function useRAF(setScList: React.Dispatch<React.SetStateAction<ScInfo[]>>) {
const animationId = useRef<number>()

useEffect(() => {
const loop = () => {
const currentTime = Date.now() // 当前时间
setScList(prev =>
prev.filter(item => currentTime - item.addedTime < (item.time - item.delay) * 1000), // 过滤掉超时的项
)

animationId.current = requestAnimationFrame(loop)
}

animationId.current = requestAnimationFrame(loop)
return () => {
animationId.current && cancelAnimationFrame(animationId.current)
}
}, [])

Check warning on line 76 in components/ScList/hook.ts

View workflow job for this annotation

GitHub Actions / CI

React Hook useEffect has a missing dependency: 'setScList'. Either include it or remove the dependency array. If 'setScList' changes too often, find the parent component that defines it and wrap that definition in useCallback
}

export { useMove, useRAF }
42 changes: 4 additions & 38 deletions components/ScList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,33 @@
import { createRef, useCallback, useEffect, useRef, useState } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import { useMove } from './hook'
import { useMove, useRAF } from './hook'
import type { SCListProps, ScInfo } from './type'
import { eventBus } from '@/utils/event'
import { WS_SC_EVENT } from '@/constant'
import closeIcon from '~/assets/close.svg'
import './index.less'

interface ScInfo {
face: string
face_frame: string
uname: string
name_color: string
price: number
message: string
message_font_color: string
background_bottom_color: string
background_color: string
id: number
time: number
nodeRef: React.RefObject<HTMLDivElement | unknown>
delay: number
}

interface SCListProps {
scDocument: Document
}

function SCList(props: SCListProps) {
const { scDocument } = props
const [scList, setScList] = useState<ScInfo[]>([])
const scListRef = useRef<HTMLDivElement>(null)
const { left, bottom, maxHeight } = useMove(scListRef, scDocument)
const timeoutMap = useRef(new Map<number, NodeJS.Timeout>())
useRAF(setScList)

const Listener = useCallback((scInfo: ScInfo) => {
const existDeleteIdList: unknown = JSON.parse(sessionStorage.getItem('deleteId') ?? 'null')
if (Array.isArray(existDeleteIdList) && existDeleteIdList.includes(scInfo.id)) {
console.log(`该id已被删除`)
return
}
setScList(prev => prev.concat({ ...scInfo, nodeRef: createRef() }))
const { id, time } = scInfo
if (!timeoutMap.current.has(id)) {
const timeout = setTimeout(() => {
setScList(prev => prev.filter(item => item.id !== id))
}, time * 1000)

timeoutMap.current.set(id, timeout)
}
setScList(prev => prev.concat({ ...scInfo, nodeRef: createRef(), addedTime: Date.now() }))
}, [])

useEffect(() => {
eventBus.subscribe(WS_SC_EVENT, Listener)

let timeoutMapRefValue: Map<number, NodeJS.Timeout> | null = null

if (timeoutMap.current)
timeoutMapRefValue = timeoutMap.current

return () => {
eventBus.unsubscribe(WS_SC_EVENT, Listener)
if (timeoutMapRefValue?.size && timeoutMapRefValue.size > 0)
for (const [_, value] of timeoutMapRefValue.entries()) clearTimeout(value)
}
}, [Listener])

Expand Down
20 changes: 20 additions & 0 deletions components/ScList/type.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export interface ScInfo {
face: string
face_frame: string
uname: string
name_color: string
price: number
message: string
message_font_color: string
background_bottom_color: string
background_color: string
id: number
time: number
nodeRef: React.RefObject<HTMLDivElement | unknown>
delay: number
addedTime: number
}

export interface SCListProps {
scDocument: Document
}
110 changes: 65 additions & 45 deletions dev/testData.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
export const testData = {
cmd: 'SUPER_CHAT_MESSAGE',
data: {
background_bottom_color: '#2A60B2',
background_color: '#EDF5FF',
background_color_end: '#405D85',
background_color_start: '#3171D2',
background_bottom_color: '#E2B52B',
background_color: '#FFF1C5',
background_color_end: '#EEBE5C',
background_color_start: '#EAB400',
background_icon: '',
background_image: '',
background_price_color: '#7497CD',
background_price_color: '#ECCF75',
color_point: 0.7,
dmscore: 42,
end_time: 1720370029,
dmscore: 714,
end_time: 1735305082,
gift: {
gift_id: 12000,
gift_name: '醒目留言',
Expand All @@ -21,88 +21,108 @@ export const testData = {
medal_id: 0,
name: '',
},
id: 10032350,
id: 11249259,
is_mystery: false,
is_ranked: 0,
is_send_audit: 1,
medal_info: {
anchor_roomid: 0,
anchor_uname: '',
guard_level: 0,
anchor_roomid: 545068,
anchor_uname: '老实憨厚的笑笑',
guard_level: 3,
icon_id: 0,
is_lighted: 0,
medal_color: '',
medal_color_border: 0,
medal_color_end: 0,
medal_color_start: 0,
medal_level: 0,
medal_name: '',
is_lighted: 1,
medal_color: '#1a544b',
medal_color_border: 6809855,
medal_color_end: 5414290,
medal_color_start: 1725515,
medal_level: 24,
medal_name: '德云色',
special: '',
target_id: 0,
target_id: 8739477,
},
message: '这波换啊bin已经死了',
message_font_color: '#A3F6FF',
message: '感谢牛场四少的陪伴,希望你们越播越好',
message_font_color: '#72110E',
message_trans: '',
price: 30,
price: 100,
rate: 1000,
start_time: 1720369969,
time: 60,
delay: 10,
token: '43C86633',
start_time: 1735304782,
time: 300,
token: '12E079E9',
trans_mark: 0,
ts: 1720369969,
uid: 17100069,
ts: 1735304782,
uid: 400307833,
uinfo: {
base: {
face: 'https://i0.hdslb.com/bfs/face/edab685f18a8ab95d47a52828d92d8eade628b7a.jpg',
face: 'http://i1.hdslb.com/bfs/face/6f68ad0487e7186ddb14e3eb6a5d9b80f6179d29.jpg',
is_mystery: false,
name: 'theve1',
name: '丘比特会一直在',
name_color: 0,
name_color_str: '#666666',
name_color_str: '#00D1F1',
official_info: {
desc: '',
role: 0,
title: '',
type: -1,
},
origin_info: {
face: 'https://i0.hdslb.com/bfs/face/edab685f18a8ab95d47a52828d92d8eade628b7a.jpg',
name: 'theve1',
face: 'http://i1.hdslb.com/bfs/face/6f68ad0487e7186ddb14e3eb6a5d9b80f6179d29.jpg',
name: '丘比特会一直在',
},
risk_ctrl_info: null,
},
guard: {
expired_str: '',
level: 0,
expired_str: '2025-01-26 23:59:59',
level: 3,
},
guard_leader: null,
medal: null,
medal: {
color: 1725515,
color_border: 6809855,
color_end: 5414290,
color_start: 1725515,
guard_icon: 'https://i0.hdslb.com/bfs/live/143f5ec3003b4080d1b5f817a9efdca46d631945.png',
guard_level: 3,
honor_icon: '',
id: 0,
is_light: 1,
level: 24,
name: '德云色',
ruid: 8739477,
score: 50012683,
typ: 0,
user_receive_count: 0,
v2_medal_color_border: '#5FC7F4FF',
v2_medal_color_end: '#43B3E3CC',
v2_medal_color_level: '#00308C99',
v2_medal_color_start: '#43B3E3CC',
v2_medal_color_text: '#FFFFFFFF',
},
title: {
old_title_css_id: '',
title_css_id: '',
},
uhead_frame: null,
uid: 17100069,
uid: 400307833,
wealth: null,
},
user_info: {
face: 'https://i0.hdslb.com/bfs/face/edab685f18a8ab95d47a52828d92d8eade628b7a.jpg',
face_frame: '',
guard_level: 0,
face: 'http://i1.hdslb.com/bfs/face/6f68ad0487e7186ddb14e3eb6a5d9b80f6179d29.jpg',
face_frame: 'https://i0.hdslb.com/bfs/live/80f732943cc3367029df65e267960d56736a82ee.png',
guard_level: 3,
is_main_vip: 1,
is_svip: 0,
is_vip: 0,
level_color: '#969696',
manager: 0,
name_color: '#666666',
name_color: '#00D1F1',
title: '',
uname: 'theve1',
user_level: 1,
uname: '丘比特会一直在',
user_level: 10,
},
},
is_report: true,
msg_id: '16680793749872640:10:1000',
msg_id: '24510937039372802:100:1000',
p_is_ack: true,
p_msg_type: 1,
send_time: 1720369969153,
send_time: 1735304782251,
}
11 changes: 6 additions & 5 deletions entrypoints/fullScreen.content/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import SCList from '@/components/ScList'
import type { DanmuDataProps } from '@/utils'
import { processData } from '@/utils'

// import { testData } from "../dev/testData";
// import { testData } from "@/dev/testData";

let isFirst = true
let isMount = false
Expand Down Expand Up @@ -37,10 +37,11 @@ export function mount(log: string) {
videoDom?.parentNode?.appendChild(existElement)
root = createRoot(existElement)
root.render(<SCList scDocument={isInIframe ? (getVideoDomFromIframe().contentDocument as Document) : document} />)

// setTimeout(() => {
// processData(testData);
// }, 1000);
// processData({ ...testData, data: { ...testData.data, time: 10, delay: 5 } });

// }, 1000);
void getInfo()
}

Expand All @@ -67,7 +68,7 @@ function injectIframeCss() {
console.log(
`extension css文件路径:`,
// @ts-expect-error: 实际是有的
browser.runtime.getURL('/content-scripts/content.css'),
browser.runtime.getURL('/content-scripts/fullScreen.css'),
)

isInIframe = true
Expand All @@ -76,7 +77,7 @@ function injectIframeCss() {

link.href = browser.runtime.getURL(
// @ts-expect-error: 实际是有的
'/content-scripts/content.css',
'/content-scripts/fullScreen.css',
) // 扩展中的 CSS 文件路径
videoIframe.contentDocument.head.appendChild(link)
}
Expand Down
8 changes: 7 additions & 1 deletion vite-plugin-replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ interface PluginOptions {
replacement: string
}

export function ReplaceUnsafeWindowPlugin(options: PluginOptions) {
interface PluginReturn {
name: string
apply: 'build'
closeBundle: () => void
}

export function ReplaceUnsafeWindowPlugin(options: PluginOptions): PluginReturn {
return {
name: 'vite-plugin-replace-unsafeWindow',
apply: 'build',
Expand Down

0 comments on commit 3df5a89

Please sign in to comment.