diff --git a/.eslintignore b/.eslintignore index 7b310a6..fd5d183 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,3 +4,4 @@ node_modules/ postcss.config.cjs vite.config.ts vite-env.d.ts +manifest.config.ts \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs index b3b3375..aaaa108 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,9 +25,12 @@ module.exports = { "@typescript-eslint/no-empty-interface": "warn", "@typescript-eslint/no-unused-vars": "warn", "@typescript-eslint/strict-boolean-expressions": "warn", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/no-non-null-assertion": "warn", "@typescript-eslint/object-curly-spacing": "off", "@typescript-eslint/no-misused-promises": "off", "@typescript-eslint/space-infix-ops": "off", + "@typescript-eslint/no-floating-promises": "off", "operator-linebreak": "off", "@typescript-eslint/space-before-function-paren": "off", "@typescript-eslint/comma-dangle": "off" diff --git a/package.json b/package.json index 3b1125d..dcbee55 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "dependencies": { "@crxjs/vite-plugin": "^1.0.14", "@kky002/kky-hooks": "^1.2.1", - "@kky002/kky-message": "^0.0.7", + "@kky002/kky-message": "^0.1.8", "@kky002/kky-ui": "^1.0.9", "@kky002/kky-util": "^1.13.13", "@logto/react": "1.0.0-beta.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 519c6b4..832dcd4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^1.2.1 version: 1.2.1 '@kky002/kky-message': - specifier: ^0.0.7 - version: 0.0.7 + specifier: ^0.1.8 + version: 0.1.8 '@kky002/kky-ui': specifier: ^1.0.9 version: 1.0.9 @@ -397,8 +397,8 @@ packages: '@kky002/kky-hooks@1.2.1': resolution: {integrity: sha512-AJM2gm75TtkZqOPd/WX0+4h/dfjSb8HlDQLwAJsYIHRNw8MQUKu32Ih6OxhKL2l9pdPsuj+S9/lBc4Cwu4tP+Q==} - '@kky002/kky-message@0.0.7': - resolution: {integrity: sha512-0qyamYhR+TT79TMbTL4frKTdOZZIObdvbDbmIT1Wu2GafxsIg249FxnW65ERqPNCZ+w5eNCK121EB11+txNFHQ==} + '@kky002/kky-message@0.1.8': + resolution: {integrity: sha512-NgGrM7pxxlENPAOTnN+2POAJ7YTRLppC5s++Jkox7sh7f1P+imz+HpeFXjqQmgW1NivHJTHt3ZUVXvRMJ3mELw==} '@kky002/kky-ui@1.0.9': resolution: {integrity: sha512-pepfRcLfC1eIQ1lsSJLWNr4PgdLqFLuvQMlitJy7W668yZ7qu8yAHSjg8A20R7HB4mFkJ+B96WETalOar1e/kA==} @@ -2846,7 +2846,7 @@ snapshots: lodash-es: 4.17.21 react: 18.2.0 - '@kky002/kky-message@0.0.7': + '@kky002/kky-message@0.1.8': dependencies: '@kky002/kky-util': 1.13.13 ahooks: 3.8.4(react@18.2.0) diff --git a/src/App.tsx b/src/App.tsx index 89cd89f..4c5d407 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,7 @@ import OptionsPage from './pages/OptionsPage' import {handleJson} from '@kky002/kky-util' import {useLocalStorage} from '@kky002/kky-hooks' import {Toaster} from 'react-hot-toast' -import useMessagingService from './hooks/useMessageService' +import useMessageService from './hooks/useMessageService' import MainPage from './pages/MainPage' function App() { @@ -44,7 +44,7 @@ function App() { useLocalStorage('chrome_client', STORAGE_TEMP, savedTempData, onLoadTemp) // services - useMessagingService() + useMessageService() return
diff --git a/src/chrome/background.ts b/src/chrome/background.ts index b640ae2..7bd9c66 100644 --- a/src/chrome/background.ts +++ b/src/chrome/background.ts @@ -34,6 +34,9 @@ const methods: { CLOSE_SIDE_PANEL: async (params, context) => { closeSidePanel() }, + GET_TAB_ID: async (params, context) => { + return context.tabId + }, ADD_TASK: async (params, context) => { // 新建任务 const task: Task = { @@ -89,14 +92,12 @@ chrome.runtime.onMessage.addListener((event: any, sender: chrome.runtime.Message return true } else if (event.type === 'syncSet') { // sync.set chrome.storage.sync.set(event.items).catch(console.error) - return } else if (event.type === 'syncRemove') { // sync.remove chrome.storage.sync.remove(event.keys).catch(console.error) - return } }) -//点击扩展图标 +// 点击扩展图标 chrome.action.onClicked.addListener(async (tab) => { chrome.storage.sync.get(STORAGE_ENV, (envDatas) => { const envDataStr = envDatas[STORAGE_ENV] @@ -115,7 +116,7 @@ chrome.action.onClicked.addListener(async (tab) => { }) } else { closeSidePanel() - extensionMessaging.sendMessage(null, tab.id!, TAG_TARGET_INJECT, 'TOGGLE_DISPLAY').catch(console.error) + extensionMessaging.sendMessage(false, tab.id!, TAG_TARGET_INJECT, 'TOGGLE_DISPLAY').catch(console.error) } }) }) diff --git a/src/components/ApiKeyReminder.tsx b/src/components/ApiKeyReminder.tsx index 6cf19c7..9dc8b97 100644 --- a/src/components/ApiKeyReminder.tsx +++ b/src/components/ApiKeyReminder.tsx @@ -1,14 +1,14 @@ -import React from 'react'; -import { useAppSelector } from '../hooks/redux'; -import { openOptionsPage } from '../utils/chromeUtils'; +import React from 'react' +import { useAppSelector } from '../hooks/redux' +import { openOptionsPage } from '../utils/chromeUtils' const ApiKeyReminder: React.FC = () => { - const apiKey = useAppSelector(state => state.env.envData.apiKey); - const geminiApiKey = useAppSelector(state => state.env.envData.geminiApiKey); - const aiType = useAppSelector(state => state.env.envData.aiType); + const apiKey = useAppSelector(state => state.env.envData.apiKey) + const geminiApiKey = useAppSelector(state => state.env.envData.geminiApiKey) + const aiType = useAppSelector(state => state.env.envData.aiType) if ((aiType === 'gemini' && geminiApiKey) || (aiType !== 'gemini' && apiKey)) { - return null; + return null } return ( @@ -21,7 +21,7 @@ const ApiKeyReminder: React.FC = () => { 设置 →
- ); -}; + ) +} -export default ApiKeyReminder; \ No newline at end of file +export default ApiKeyReminder diff --git a/src/components/Body.tsx b/src/components/Body.tsx index ba01226..b87aca9 100644 --- a/src/components/Body.tsx +++ b/src/components/Body.tsx @@ -127,7 +127,7 @@ const Body = () => { } toast.success(`已添加${segments_.length}个总结任务!`) } - }, [addSummarizeTask, curSummaryType, dispatch, envData.aiType, envData.apiKey, envData.geminiApiKey, segments]) + }, [addSummarizeTask, curSummaryType, envData.aiType, envData.apiKey, envData.geminiApiKey, segments]) const onFoldAll = useCallback(() => { dispatch(setFoldAll(!foldAll)) diff --git a/src/components/DebateChat.tsx b/src/components/DebateChat.tsx index 97780c0..2df24d5 100644 --- a/src/components/DebateChat.tsx +++ b/src/components/DebateChat.tsx @@ -1,8 +1,8 @@ -import { useAppSelector } from '@/hooks/redux'; -import React from 'react'; +import { useAppSelector } from '@/hooks/redux' +import React from 'react' const DebateChat: React.FC = ({ messages }) => { - const fontSize = useAppSelector(state => state.env.envData.fontSize) + const fontSize = useAppSelector(state => state.env.envData.fontSize) return (
@@ -37,7 +37,7 @@ const DebateChat: React.FC = ({ messages }) => { ))}
- ); -}; + ) +} -export default DebateChat; \ No newline at end of file +export default DebateChat diff --git a/src/components/MoreBtn.tsx b/src/components/MoreBtn.tsx index e429f51..ea98cf7 100644 --- a/src/components/MoreBtn.tsx +++ b/src/components/MoreBtn.tsx @@ -11,12 +11,12 @@ import {Placement} from '@popperjs/core/lib/enums' import {useAppDispatch, useAppSelector} from '../hooks/redux' import {setEnvData, setTempData} from '../redux/envReducer' import {EventBusContext} from '../Router' -import {DEFAULT_USE_PORT, EVENT_EXPAND} from '../consts/const' +import {EVENT_EXPAND} from '../consts/const' import {formatSrtTime, formatTime, formatVttTime} from '../utils/util' import {downloadText, openUrl} from '@kky002/kky-util' import toast from 'react-hot-toast' import {getSummarize} from '../utils/bizUtil' -import dayjs from 'dayjs'; +import dayjs from 'dayjs' import { useMessage } from '@/hooks/useMessageService' interface Props { @@ -68,7 +68,7 @@ const MoreBtn = (props: Props) => { const segments = useAppSelector(state => state.env.segments) const url = useAppSelector(state => state.env.url) const title = useAppSelector(state => state.env.title) - const ctime = useAppSelector(state => state.env.ctime) //时间戳,单位s + const ctime = useAppSelector(state => state.env.ctime) // 时间戳,单位s const author = useAppSelector(state => state.env.author) const curSummaryType = useAppSelector(state => state.env.tempData.curSummaryType) @@ -81,7 +81,7 @@ const MoreBtn = (props: Props) => { let fileName = title let s, suffix - let time = ctime ? dayjs(ctime * 1000).format('YYYY-MM-DD HH:mm:ss') : '' // 2024-05-01 12:00:00 + const time = ctime ? dayjs(ctime * 1000).format('YYYY-MM-DD HH:mm:ss') : '' // 2024-05-01 12:00:00 if (!downloadType || downloadType === 'text') { s = `${title??'无标题'}\n${url??'无链接'}\n${author??'无作者'} ${time}\n\n` for (const item of data.body) { @@ -162,11 +162,11 @@ const MoreBtn = (props: Props) => { }).catch(console.error) } setMoreVisible(false) - }, [curSummaryType, data, downloadType, segments, title, url]) + }, [author, ctime, curSummaryType, data, downloadType, segments, title, url]) const downloadAudioCallback = useCallback(() => { sendInject(null, 'DOWNLOAD_AUDIO', {}) - }, []) + }, [sendInject]) const selectCallback = useCallback((e: any) => { dispatch(setTempData({ diff --git a/src/components/RateExtension.tsx b/src/components/RateExtension.tsx index dcb4bb8..0b5ea06 100644 --- a/src/components/RateExtension.tsx +++ b/src/components/RateExtension.tsx @@ -1,14 +1,14 @@ -import React, { useState } from 'react'; -import { FaStar } from 'react-icons/fa'; -import { IoMdClose } from 'react-icons/io'; -import { setTempData } from '../redux/envReducer'; -import { useAppDispatch, useAppSelector } from '../hooks/redux'; -import { openUrl } from '@kky002/kky-util'; -import { isEdgeBrowser } from '../utils/util'; +import React, { useState } from 'react' +import { FaStar } from 'react-icons/fa' +import { IoMdClose } from 'react-icons/io' +import { setTempData } from '../redux/envReducer' +import { useAppDispatch, useAppSelector } from '../hooks/redux' +import { openUrl } from '@kky002/kky-util' +import { isEdgeBrowser } from '../utils/util' const RateExtension: React.FC = () => { const dispatch = useAppDispatch() - const [isHovered, setIsHovered] = useState(false); + const [isHovered, setIsHovered] = useState(false) const reviewed = useAppSelector(state => state.env.tempData.reviewed) const handleRateClick = () => { @@ -21,9 +21,9 @@ const RateExtension: React.FC = () => { } else { openUrl('https://chromewebstore.google.com/webstore/detail/bciglihaegkdhoogebcdblfhppoilclp/reviews') } - }; + } - if (reviewed === true || reviewed === undefined) return null; + if (reviewed === true || reviewed === undefined) return null return (
@@ -52,7 +52,7 @@ const RateExtension: React.FC = () => {
- ); -}; + ) +} -export default RateExtension; \ No newline at end of file +export default RateExtension diff --git a/src/consts/const.ts b/src/consts/const.ts index 1084233..9097d7c 100644 --- a/src/consts/const.ts +++ b/src/consts/const.ts @@ -188,7 +188,7 @@ Provide an example to illustrate the expected output: ] \`\`\` `, -[PROMPT_TYPE_SUMMARIZE_DEBATE]: `You are a helpful assistant skilled at generating debates based on video subtitles. + [PROMPT_TYPE_SUMMARIZE_DEBATE]: `You are a helpful assistant skilled at generating debates based on video subtitles. ## Context diff --git a/src/hooks/useMessageService.ts b/src/hooks/useMessageService.ts index dc4545c..078c75e 100644 --- a/src/hooks/useMessageService.ts +++ b/src/hooks/useMessageService.ts @@ -1,14 +1,14 @@ import { setAuthor, setCtime, setCurFetched, setCurInfo, setData, setInfos, setTitle, setUrl } from '@/redux/envReducer' -import { useAppDispatch } from './redux' +import { useAppDispatch, useAppSelector } from './redux' import { AllAPPMessages, AllExtensionMessages, AllInjectMessages } from '@/message-typings' -import { DEFAULT_USE_PORT } from '@/consts/const' import { useMessaging, useMessagingService } from '@kky002/kky-message' import { useMemoizedFn } from 'ahooks' const useMessageService = () => { const dispatch = useAppDispatch() - - //methods + const envData = useAppSelector((state) => state.env.envData) + + // methods const methodsFunc: () => { [K in AllAPPMessages['method']]: (params: Extract['params'], context: MethodContext) => Promise } = useMemoizedFn(() => ({ @@ -28,8 +28,8 @@ const useMessageService = () => { }, })) - useMessagingService(DEFAULT_USE_PORT, methodsFunc) + useMessagingService(!!envData.sidePanel, methodsFunc) } export default useMessageService -export const useMessage = useMessaging \ No newline at end of file +export const useMessage = useMessaging diff --git a/src/hooks/useSubtitle.ts b/src/hooks/useSubtitle.ts index d2c2838..2176b7b 100644 --- a/src/hooks/useSubtitle.ts +++ b/src/hooks/useSubtitle.ts @@ -9,18 +9,18 @@ const useSubtitle = () => { const reviewAction = useAppSelector(state => state.env.reviewAction) const reviewActions = useAppSelector(state => state.env.tempData.reviewActions) const {sendInject} = useMessage(!!envData.sidePanel) - + const move = useCallback((time: number, togglePause: boolean) => { sendInject(null, 'MOVE', {time, togglePause}) - //review action + // review action if (reviewed === undefined && !reviewAction) { dispatch(setReviewAction(true)) dispatch(setTempData({ reviewActions: (reviewActions ?? 0) + 1 })) } - }, [dispatch, reviewAction, reviewActions, reviewed]) + }, [dispatch, reviewAction, reviewActions, reviewed, sendInject]) const scrollIntoView = useCallback((ref: React.RefObject) => { ref.current?.scrollIntoView({behavior: 'smooth', block: 'center'}) diff --git a/src/hooks/useSubtitleService.ts b/src/hooks/useSubtitleService.ts index 81ea274..46ba9cf 100644 --- a/src/hooks/useSubtitleService.ts +++ b/src/hooks/useSubtitleService.ts @@ -45,7 +45,7 @@ const useSubtitleService = () => { const reviewActions = useAppSelector(state => state.env.tempData.reviewActions) const {sendInject} = useMessage(!!envData.sidePanel) - //如果reviewActions达到15次,则设置reviewed为false + // 如果reviewActions达到15次,则设置reviewed为false useEffect(() => { if (reviewed === undefined && reviewActions && reviewActions >= 15) { dispatch(setTempData({ @@ -74,7 +74,7 @@ const useSubtitleService = () => { dispatch(setCurInfo(infos[0])) dispatch(setCurFetched(false)) } - }, [curInfo, dispatch, envData.autoExpand, envReady, fold, infos]) + }, [curInfo, dispatch, envData.autoExpand, envReady, fold, infos, envData.sidePanel]) // 获取 useEffect(() => { if (curInfo && !curFetched) { @@ -86,15 +86,17 @@ const useSubtitleService = () => { dispatch(setCurFetched(true)) dispatch(setData(data)) - console.log('subtitle', data) + console.debug('subtitle', data) }) } - }, [curFetched, curInfo]) + }, [curFetched, curInfo, dispatch, sendInject]) useAsyncEffect(async () => { // 初始获取列表 - sendInject(null, 'REFRESH_VIDEO_INFO', {force: true}) - }, []) + if (envReady) { + sendInject(null, 'REFRESH_VIDEO_INFO', {force: true}) + } + }, [envReady, sendInject]) useAsyncEffect(async () => { // 更新设置信息 @@ -103,11 +105,11 @@ const useSubtitleService = () => { if (envData.sidePanel) { // get screen height dispatch(setTotalHeight(window.innerHeight)) - }else { + } else { dispatch(setTotalHeight(Math.min(Math.max(info.totalHeight, TOTAL_HEIGHT_MIN), TOTAL_HEIGHT_MAX))) } }) - }, [envData.sidePanel, infos]) + }, [envData.sidePanel, infos, sendInject]) // 更新当前位置 useEffect(() => { @@ -212,7 +214,7 @@ const useSubtitleService = () => { } else { sendInject(null, 'HIDE_TRANS', {}) } - }, [autoTranslate, curIdx, hideOnDisableAutoTranslate, transResults]) + }, [autoTranslate, curIdx, hideOnDisableAutoTranslate, sendInject, transResults]) } export default useSubtitleService diff --git a/src/hooks/useTranslate.ts b/src/hooks/useTranslate.ts index 2f503a4..f4f04d3 100644 --- a/src/hooks/useTranslate.ts +++ b/src/hooks/useTranslate.ts @@ -139,10 +139,10 @@ const useTranslate = () => { dispatch(addTaskId(task.id)) } } - }, [data?.body, envData, language.name, title, dispatch]) + }, [data?.body, envData, language.name, title, dispatch, sendExtension]) const addSummarizeTask = useCallback(async (type: SummaryType, segment: Segment) => { - //review action + // review action if (reviewed === undefined && !reviewAction) { dispatch(setReviewAction(true)) dispatch(setTempData({ @@ -208,7 +208,7 @@ const useTranslate = () => { const task = await sendExtension(null, 'ADD_TASK', {taskDef}) dispatch(addTaskId(task.id)) } - }, [dispatch, envData, summarizeLanguage.name, title]) + }, [dispatch, envData, reviewAction, reviewActions, reviewed, sendExtension, summarizeLanguage.name, title]) const addAskTask = useCallback(async (id: string, segment: Segment, question: string) => { if (segment.text.length >= SUMMARIZE_THRESHOLD) { @@ -265,7 +265,7 @@ const useTranslate = () => { const task = await sendExtension(null, 'ADD_TASK', {taskDef}) dispatch(addTaskId(task.id)) } - }, [dispatch, envData, summarizeLanguage.name, title]) + }, [dispatch, envData, sendExtension, summarizeLanguage.name, title]) const handleTranslate = useMemoizedFn((task: Task, content: string) => { let map: {[key: string]: string} = {} @@ -355,7 +355,7 @@ const useTranslate = () => { } else { dispatch(delTaskId(taskId)) } - }, [dispatch, envData.aiType, handleAsk, handleSummarize, handleTranslate]) + }, [dispatch, envData.aiType, handleAsk, handleSummarize, handleTranslate, sendExtension]) return {getFetch, getTask, addTask, addSummarizeTask, addAskTask} } diff --git a/src/inject/inject.ts b/src/inject/inject.ts index e0e826d..25a88e9 100644 --- a/src/inject/inject.ts +++ b/src/inject/inject.ts @@ -13,7 +13,7 @@ const debug = (...args: any[]) => { return } - //读取envData + // 读取envData const envDataStr = (await chrome.storage.sync.get(STORAGE_ENV))[STORAGE_ENV] let sidePanel: boolean | null = null let manualInsert: boolean | null = null @@ -94,7 +94,7 @@ const debug = (...args: any[]) => { iframe.dataset[vKey] = danmukuBox?.dataset[vKey] } - //insert before first child + // insert before first child danmukuBox?.insertBefore(iframe, danmukuBox?.firstChild) // show badge @@ -114,7 +114,7 @@ const debug = (...args: any[]) => { if (danmukuBox) { clearInterval(timerIframe) - //延迟插入iframe(插入太快,网络较差时容易出现b站网页刷新,原因暂时未知,可能b站的某种机制?) + // 延迟插入iframe(插入太快,网络较差时容易出现b站网页刷新,原因暂时未知,可能b站的某种机制?) setTimeout(createIframe, 1500) } }, 1000) @@ -140,6 +140,7 @@ const debug = (...args: any[]) => { // fix: https://github.com/IndieKKY/bilibili-subtitle/issues/5 // 处理稍后再看的url( https://www.bilibili.com/list/watchlater?bvid=xxx&oid=xxx ) const pathSearchs: Record = {} + // eslint-disable-next-line no-return-assign location.search.slice(1).replace(/([^=&]*)=([^=&]*)/g, (matchs, a, b, c) => pathSearchs[a] = b) // bvid @@ -158,21 +159,21 @@ const debug = (...args: any[]) => { lastAidOrBvid = aidOrBvid if (aidOrBvid) { - //aid,pages - let cid + // aid,pages + let cid: string | undefined let subtitles - if (aidOrBvid.toLowerCase().startsWith('av')) {//avxxx + if (aidOrBvid.toLowerCase().startsWith('av')) { // avxxx aid = parseInt(aidOrBvid.slice(2)) - pages = await fetch(`https://api.bilibili.com/x/player/pagelist?aid=${aid}`, { credentials: 'include' }).then(res => res.json()).then(res => res.data) + pages = await fetch(`https://api.bilibili.com/x/player/pagelist?aid=${aid}`, { credentials: 'include' }).then(async res => await res.json()).then(res => res.data) cid = pages[0].cid ctime = pages[0].ctime author = pages[0].owner?.name title = pages[0].part - await fetch(`https://api.bilibili.com/x/player/wbi/v2?aid=${aid}&cid=${cid}`, { credentials: 'include' }).then(res => res.json()).then(res => { + await fetch(`https://api.bilibili.com/x/player/wbi/v2?aid=${aid}&cid=${cid!}`, { credentials: 'include' }).then(async res => await res.json()).then(res => { subtitles = res.data.subtitle.subtitles }) - } else {//bvxxx - await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${aidOrBvid}`, { credentials: 'include' }).then(res => res.json()).then(async res => { + } else { // bvxxx + await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${aidOrBvid}`, { credentials: 'include' }).then(async res => await res.json()).then(async res => { title = res.data.title aid = res.data.aid cid = res.data.cid @@ -180,12 +181,12 @@ const debug = (...args: any[]) => { author = res.data.owner?.name pages = res.data.pages }) - await fetch(`https://api.bilibili.com/x/player/wbi/v2?aid=${aid}&cid=${cid}`, { credentials: 'include' }).then(res => res.json()).then(res => { + await fetch(`https://api.bilibili.com/x/player/wbi/v2?aid=${aid!}&cid=${cid!}`, { credentials: 'include' }).then(async res => await res.json()).then(res => { subtitles = res.data.subtitle.subtitles }) } - //pagesMap + // pagesMap pagesMap = {} pages.forEach(page => { pagesMap[page.page + ''] = page @@ -193,7 +194,7 @@ const debug = (...args: any[]) => { debug('refreshVideoInfo: ', aid, cid, pages, subtitles) - //send setVideoInfo + // send setVideoInfo runtime.injectMessaging.sendApp(!!sidePanel, 'SET_VIDEO_INFO', { url: location.origin + location.pathname, title, @@ -219,7 +220,7 @@ const debug = (...args: any[]) => { const p = urlSearchParams.get('p') || 1 const page = pagesMap[p] if (!page) return - const cid = page.cid + const cid: number | null = page.cid if (aid !== lastAid || cid !== lastCid) { debug('refreshSubtitles', aid, cid) @@ -230,9 +231,9 @@ const debug = (...args: any[]) => { fetch(`https://api.bilibili.com/x/player/wbi/v2?aid=${aid}&cid=${cid}`, { credentials: 'include', }) - .then(res => res.json()) + .then(async res => await res.json()) .then(res => { - //remove elements with empty subtitle_url + // remove elements with empty subtitle_url res.data.subtitle.subtitles = res.data.subtitle.subtitles.filter((item: any) => item.subtitle_url) if (res.data.subtitle.subtitles.length > 0) { runtime.injectMessaging.sendApp(!!sidePanel, 'SET_INFOS', { @@ -283,7 +284,7 @@ const debug = (...args: any[]) => { if (url.startsWith('http://')) { url = url.replace('http://', 'https://') } - return await fetch(url).then(res => res.json()) + return await fetch(url).then(async res => await res.json()) }, GET_VIDEO_STATUS: async (params) => { const video = getVideoElement() @@ -336,7 +337,7 @@ const debug = (...args: any[]) => { runtime.showTrans = false runtime.curTrans = undefined - let text = document.getElementById('trans-result-text') + const text = document.getElementById('trans-result-text') if (text) { text.style.display = 'none' } @@ -357,7 +358,7 @@ const debug = (...args: any[]) => { const playInfo = JSON.parse(html.match(/window.__playinfo__=(.+?)<\/script/)?.[1] ?? '{}') const audioUrl = playInfo.data.dash.audio[0].baseUrl - fetch(audioUrl).then(res => res.blob()).then(blob => { + fetch(audioUrl).then(async res => await res.blob()).then(blob => { const a = document.createElement('a') a.href = URL.createObjectURL(blob) a.download = `${title}.m4s` diff --git a/src/message-typings.d.ts b/src/message-typings.d.ts index 6c52b59..1c6c865 100644 --- a/src/message-typings.d.ts +++ b/src/message-typings.d.ts @@ -1,12 +1,12 @@ import {ExtensionMessage, InjectMessage, AppMessage} from '@kky002/kky-message' -//extension +// extension interface ExtensionCloseSidePanelMessage extends ExtensionMessage { - method: 'CLOSE_SIDE_PANEL'; + method: 'CLOSE_SIDE_PANEL' } interface ExtensionAddTaskMessage extends ExtensionMessage<{ taskDef: TaskDef }, Task> { - method: 'ADD_TASK'; + method: 'ADD_TASK' } interface ExtensionGetTaskMessage extends ExtensionMessage<{ taskId: string }, { @@ -15,76 +15,73 @@ interface ExtensionGetTaskMessage extends ExtensionMessage<{ taskId: string }, { } | { code: 'not_found' }> { - method: 'GET_TASK'; + method: 'GET_TASK' } interface ExtensionShowFlagMessage extends ExtensionMessage<{ show: boolean }> { - method: 'SHOW_FLAG'; + method: 'SHOW_FLAG' } -export type AllExtensionMessages = ExtensionCloseSidePanelMessage | ExtensionAddTaskMessage | ExtensionGetTaskMessage | ExtensionShowFlagMessage +interface ExtensionGetTabIdMessage extends ExtensionMessage<{ show: boolean }> { + method: 'GET_TAB_ID' +} +export type AllExtensionMessages = ExtensionGetTabIdMessage | ExtensionCloseSidePanelMessage | ExtensionAddTaskMessage | ExtensionGetTaskMessage | ExtensionShowFlagMessage - - -//inject +// inject interface InjectToggleDisplayMessage extends InjectMessage<{}> { - method: 'TOGGLE_DISPLAY'; + method: 'TOGGLE_DISPLAY' } interface InjectFoldMessage extends InjectMessage<{ fold: boolean }> { - method: 'FOLD'; + method: 'FOLD' } interface InjectMoveMessage extends InjectMessage<{ time: number, togglePause: boolean }> { - method: 'MOVE'; + method: 'MOVE' } interface InjectGetSubtitleMessage extends InjectMessage<{ info: any }> { - method: 'GET_SUBTITLE'; + method: 'GET_SUBTITLE' } interface InjectGetVideoStatusMessage extends InjectMessage<{}> { - method: 'GET_VIDEO_STATUS'; + method: 'GET_VIDEO_STATUS' } interface InjectGetVideoElementInfoMessage extends InjectMessage<{}> { - method: 'GET_VIDEO_ELEMENT_INFO'; + method: 'GET_VIDEO_ELEMENT_INFO' } interface InjectRefreshVideoInfoMessage extends InjectMessage<{ force: boolean }> { - method: 'REFRESH_VIDEO_INFO'; + method: 'REFRESH_VIDEO_INFO' } interface InjectUpdateTransResultMessage extends InjectMessage<{ result: string }> { - method: 'UPDATE_TRANS_RESULT'; + method: 'UPDATE_TRANS_RESULT' } interface InjectHideTransMessage extends InjectMessage<{}> { - method: 'HIDE_TRANS'; + method: 'HIDE_TRANS' } interface InjectPlayMessage extends InjectMessage<{ play: boolean }> { - method: 'PLAY'; + method: 'PLAY' } interface InjectDownloadAudioMessage extends InjectMessage<{}> { - method: 'DOWNLOAD_AUDIO'; + method: 'DOWNLOAD_AUDIO' } export type AllInjectMessages = InjectToggleDisplayMessage | InjectFoldMessage | InjectMoveMessage | InjectGetSubtitleMessage | InjectGetVideoStatusMessage | InjectGetVideoElementInfoMessage | InjectRefreshVideoInfoMessage | InjectUpdateTransResultMessage | InjectHideTransMessage | InjectPlayMessage | InjectDownloadAudioMessage - - - -//app +// app interface AppSetInfosMessage extends AppMessage<{ infos: any }> { - method: 'SET_INFOS'; + method: 'SET_INFOS' } interface AppSetVideoInfoMessage extends AppMessage<{ url: string, title: string, aid: number | null, ctime: number | null, author?: string, pages: any, infos: any }> { - method: 'SET_VIDEO_INFO'; + method: 'SET_VIDEO_INFO' } export type AllAPPMessages = AppSetInfosMessage | AppSetVideoInfoMessage - diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index c608aca..7df726a 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -18,7 +18,7 @@ function App() { const eventBus = useContext(EventBusContext) const totalHeight = useAppSelector(state => state.env.totalHeight) const {sendInject} = useMessage(!!envData.sidePanel) - + const foldCallback = useCallback(() => { dispatch(setFold(!fold)) sendInject(null, 'FOLD', {fold: !fold}) diff --git a/src/pages/OptionsPage.tsx b/src/pages/OptionsPage.tsx index 8d528e8..90dc3b3 100644 --- a/src/pages/OptionsPage.tsx +++ b/src/pages/OptionsPage.tsx @@ -29,8 +29,8 @@ import {useEventChecked} from '@kky002/kky-hooks' import { FaChevronDown, FaChevronUp, FaGripfire } from 'react-icons/fa' import { useMessage } from '@/hooks/useMessageService' -const OptionCard = ({ title, children, defaultExpanded = true }: { title: React.ReactNode; children: React.ReactNode; defaultExpanded?: boolean }) => { - const [isExpanded, setIsExpanded] = useState(defaultExpanded); +const OptionCard = ({ title, children, defaultExpanded = true }: { title: React.ReactNode, children: React.ReactNode, defaultExpanded?: boolean }) => { + const [isExpanded, setIsExpanded] = useState(defaultExpanded) return (
@@ -42,8 +42,8 @@ const OptionCard = ({ title, children, defaultExpanded = true }: { title: React. {isExpanded &&
{children}
}
- ); -}; + ) +} const FormItem = (props: { title: ShowElement @@ -430,4 +430,4 @@ const OptionsPage = () => { ) } -export default OptionsPage \ No newline at end of file +export default OptionsPage diff --git a/src/redux/envReducer.ts b/src/redux/envReducer.ts index 4182600..c9b1817 100644 --- a/src/redux/envReducer.ts +++ b/src/redux/envReducer.ts @@ -50,7 +50,7 @@ interface EnvState { searchText: string searchResult: Record - //当前视频是否计算过操作 + // 当前视频是否计算过操作 reviewAction: boolean } diff --git a/src/typings.d.ts b/src/typings.d.ts index b037b8c..2c89c3e 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -7,7 +7,7 @@ interface MethodContext { interface EnvData { sidePanel?: boolean - manualInsert?: boolean //是否手动插入字幕列表 + manualInsert?: boolean // 是否手动插入字幕列表 autoExpand?: boolean flagDot?: boolean @@ -154,10 +154,10 @@ type SummaryStatus = 'init' | 'pending' | 'done' type SummaryType = 'overview' | 'keypoint' | 'brief' | 'question' | 'debate' interface DebateMessage { - side: 'pro' | 'con'; - content: string; + side: 'pro' | 'con' + content: string } interface DebateProps { - messages: DebateMessage[]; + messages: DebateMessage[] } diff --git a/src/utils/bizUtil.ts b/src/utils/bizUtil.ts index f3b4a14..d4b739c 100644 --- a/src/utils/bizUtil.ts +++ b/src/utils/bizUtil.ts @@ -115,7 +115,7 @@ export const getSummaryStr = (summary: Summary) => { s += content.map(item => { return (item.side === 'pro'?'正方:':'反方:') + item.content + '\n' }).join('\n') - } + } return s } diff --git a/src/utils/chromeUtils.ts b/src/utils/chromeUtils.ts index eaccb01..aea0a7b 100644 --- a/src/utils/chromeUtils.ts +++ b/src/utils/chromeUtils.ts @@ -1,7 +1,7 @@ export const openOptionsPage = () => { if (chrome.runtime.openOptionsPage) { - chrome.runtime.openOptionsPage(); + chrome.runtime.openOptionsPage() } else { - window.open(chrome.runtime.getURL('options.html')); + window.open(chrome.runtime.getURL('options.html')) } -}; \ No newline at end of file +} diff --git a/src/utils/util.ts b/src/utils/util.ts index 19656ee..4310591 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -1,8 +1,8 @@ import {SyntheticEvent} from 'react' export const isEdgeBrowser = () => { - const userAgent = navigator.userAgent.toLowerCase(); - return userAgent.includes('edg/') && !userAgent.includes('edge/'); + const userAgent = navigator.userAgent.toLowerCase() + return userAgent.includes('edg/') && !userAgent.includes('edge/') } export const formatTime = (time: number) => {