diff --git a/src/App.tsx b/src/App.tsx index 33e8ab3..c91c05e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,12 @@ import React, {useCallback, useContext, useEffect, useMemo} from 'react' import 'tippy.js/dist/tippy.css' import {useAppDispatch, useAppSelector} from './hooks/redux' -import {setEnvData, setEnvReady, setFold, setPage, setTempData, setTempReady} from './redux/envReducer' +import {setCurFetched, setCurInfo, setData, setEnvData, setEnvReady, setFold, setInfos, setPage, setTempData, setTempReady, setTitle, setUrl} from './redux/envReducer' import Header from './biz/Header' import Body from './biz/Body' import useSubtitleService from './hooks/useSubtitleService' import {cloneDeep} from 'lodash-es' -import {EVENT_EXPAND, MESSAGE_TO_INJECT_FOLD, PAGE_MAIN, PAGE_SETTINGS, STORAGE_ENV, STORAGE_TEMP} from './const' +import {EVENT_EXPAND, MESSAGE_TO_APP_SET_INFOS, MESSAGE_TO_APP_SET_VIDEO_INFO, MESSAGE_TO_INJECT_FOLD, PAGE_MAIN, PAGE_SETTINGS, STORAGE_ENV, STORAGE_TEMP} from './const' import {EventBusContext} from './Router' import useTranslateService from './hooks/useTranslateService' import Settings from './biz/Settings' @@ -14,9 +14,9 @@ import {handleJson} from '@kky002/kky-util' import {useLocalStorage} from '@kky002/kky-hooks' import {Toaster} from 'react-hot-toast' import {setTheme} from './util/biz_util' -import {sendInject} from './util/biz_util' import useSearchService from './hooks/useSearchService' -import useMessageService from './hooks/useMessageService' +import useMessageService from './messaging/useMessageService' +import useMessage from './messaging/useMessage' function App() { const dispatch = useAppDispatch() @@ -26,6 +26,7 @@ function App() { const eventBus = useContext(EventBusContext) const page = useAppSelector(state => state.env.page) const totalHeight = useAppSelector(state => state.env.totalHeight) + const {sendInject} = useMessage() const foldCallback = useCallback(() => { dispatch(setFold(!fold)) @@ -71,11 +72,29 @@ function App() { setTheme(envData.theme) }, [envData.theme]) + //methods + const methods = useMemo(() => ({ + [MESSAGE_TO_APP_SET_INFOS]: (params: any, from: string, context: MethodContext) => { + dispatch(setInfos(params.infos)) + dispatch(setCurInfo(undefined)) + dispatch(setCurFetched(false)) + dispatch(setData(undefined)) + return true + }, + [MESSAGE_TO_APP_SET_VIDEO_INFO]: (params: any, from: string, context: MethodContext) => { + dispatch(setInfos(params.infos)) + dispatch(setUrl(params.url)) + dispatch(setTitle(params.title)) + console.debug('video title: ', params.title) + return true + }, + }), [dispatch]) + // services useSubtitleService() useTranslateService() useSearchService() - useMessageService() + useMessageService(methods) return
{ const title = useAppSelector(state => state.env.title) const curSummaryType = useAppSelector(state => state.env.tempData.curSummaryType) + const {sendInject} = useMessage() + const downloadCallback = useCallback((download: boolean) => { if (data == null) { return diff --git a/src/chrome/background.ts b/src/chrome/background.ts index cda24e4..736df8a 100644 --- a/src/chrome/background.ts +++ b/src/chrome/background.ts @@ -1,10 +1,7 @@ import {v4} from 'uuid' import {handleTask, initTaskService, tasksMap} from './taskService' -import {MESSAGE_TARGET_EXTENSION, MESSAGE_TO_EXTENSION_ADD_TASK, MESSAGE_TO_EXTENSION_GET_TASK} from '@/const' - -const debug = (...args: any[]) => { - console.debug('[Extension]', ...args) -} +import {MESSAGE_TO_EXTENSION_ADD_TASK, MESSAGE_TO_EXTENSION_GET_TASK} from '@/const' +import ExtensionMessage from '@/messaging/ExtensionMessage' const methods: { [key: string]: (params: any, context: MethodContext) => Promise @@ -46,12 +43,12 @@ const methods: { } }, } +// 初始化backgroundMessage +const extensionMessage = new ExtensionMessage() +extensionMessage.init(methods) -/** - * Note: Return true when sending a response asynchronously. - */ chrome.runtime.onMessage.addListener((event: MessageData, sender: chrome.runtime.MessageSender, sendResponse: (result: any) => void) => { - debug((sender.tab != null) ? `tab ${sender.tab.url ?? ''} => ` : 'extension => ', event) + // debug((sender.tab != null) ? `tab ${sender.tab.url ?? ''} => ` : 'extension => ', event) // legacy if (event.type === 'syncGet') { // sync.get @@ -66,44 +63,6 @@ chrome.runtime.onMessage.addListener((event: MessageData, sender: chrome.runtime chrome.storage.sync.remove(event.keys).catch(console.error) return } - - // check event target - if (event.target !== MESSAGE_TARGET_EXTENSION) return - - const method = methods[event.method] - if (method != null) { - method(event.params, { - event, - sender, - }).then(data => sendResponse({ - success: true, - code: 200, - data, - })).catch(err => { - console.error(err) - let message - if (err instanceof Error) { - message = err.message - } else if (typeof err === 'string') { - message = err - } else { - message = 'error: ' + JSON.stringify(err) - } - sendResponse({ - success: false, - code: 500, - message, - }) - }) - return true - } else { - console.error('Unknown method:', event.method) - sendResponse({ - success: false, - code: 501, - message: 'Unknown method: ' + event.method, - }) - } }) initTaskService() diff --git a/src/chrome/backgroundUtil.ts b/src/chrome/backgroundUtil.ts deleted file mode 100644 index 54c1981..0000000 --- a/src/chrome/backgroundUtil.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const broadcastMessage = async (ignoreTabIds: number[] | undefined | null, target: string, method: string, params?: any) => { - const tabs = await chrome.tabs.query({ - discarded: false, - }) - for (const tab of tabs) { - try { - if (tab.id && ((ignoreTabIds == null) || !ignoreTabIds.includes(tab.id))) { - await chrome.tabs.sendMessage(tab.id, {target, method, params}) - } - } catch (e) { - console.error('send message to tab error', tab.id, e) - } - } -} diff --git a/src/const.tsx b/src/const.ts similarity index 100% rename from src/const.tsx rename to src/const.ts diff --git a/src/hooks/useSubtitle.ts b/src/hooks/useSubtitle.ts index 893ecfd..96a3737 100644 --- a/src/hooks/useSubtitle.ts +++ b/src/hooks/useSubtitle.ts @@ -1,15 +1,15 @@ import {useAppDispatch, useAppSelector} from './redux' import React, {useCallback} from 'react' import {setNeedScroll, setReviewAction, setTempData} from '../redux/envReducer' -import {sendInject} from '../util/biz_util' import {MESSAGE_TO_INJECT_MOVE} from '../const' - +import useMessage from '../messaging/useMessage' const useSubtitle = () => { const dispatch = useAppDispatch() const reviewed = useAppSelector(state => state.env.tempData.reviewed) const reviewAction = useAppSelector(state => state.env.reviewAction) const reviewActions = useAppSelector(state => state.env.tempData.reviewActions) - + const {sendInject} = useMessage() + const move = useCallback((time: number, togglePause: boolean) => { sendInject(MESSAGE_TO_INJECT_MOVE, {time, togglePause}) diff --git a/src/hooks/useSubtitleService.ts b/src/hooks/useSubtitleService.ts index 28ea003..758cdd9 100644 --- a/src/hooks/useSubtitleService.ts +++ b/src/hooks/useSubtitleService.ts @@ -19,8 +19,8 @@ import {EventBusContext} from '../Router' import {EVENT_EXPAND, GEMINI_TOKENS, TOTAL_HEIGHT_MAX, TOTAL_HEIGHT_MIN, WORDS_MIN, WORDS_RATE, MESSAGE_TO_INJECT_GET_VIDEO_STATUS, MESSAGE_TO_INJECT_GET_VIDEO_ELEMENT_INFO, MESSAGE_TO_INJECT_REFRESH_VIDEO_INFO, MESSAGE_TO_INJECT_HIDE_TRANS, MESSAGE_TO_INJECT_UPDATETRANSRESULT} from '../const' import {useInterval} from 'ahooks' import {getModelMaxTokens, getWholeText} from '../util/biz_util' -import {sendInject} from '../util/biz_util' import {MESSAGE_TO_INJECT_GET_SUBTITLE} from '../const' +import useMessage from '../messaging/useMessage' /** * Service是单例,类似后端的服务概念 @@ -44,6 +44,7 @@ const useSubtitleService = () => { const autoTranslate = useAppSelector(state => state.env.autoTranslate) const reviewed = useAppSelector(state => state.env.tempData.reviewed) const reviewActions = useAppSelector(state => state.env.tempData.reviewActions) + const {sendInject} = useMessage() //如果reviewActions达到15次,则设置reviewed为false useEffect(() => { diff --git a/src/hooks/useTranslate.ts b/src/hooks/useTranslate.ts index 89b84dd..dfcc97c 100644 --- a/src/hooks/useTranslate.ts +++ b/src/hooks/useTranslate.ts @@ -29,9 +29,9 @@ import { } from '../const' import toast from 'react-hot-toast' import {useMemoizedFn} from 'ahooks/es' -import {extractJsonArray, extractJsonObject, getModel, sendExtension} from '../util/biz_util' +import {extractJsonArray, extractJsonObject, getModel} from '../util/biz_util' import {formatTime} from '../util/util' - +import useMessage from '@/messaging/useMessage' const useTranslate = () => { const dispatch = useAppDispatch() const data = useAppSelector(state => state.env.data) @@ -45,7 +45,7 @@ const useTranslate = () => { const reviewed = useAppSelector(state => state.env.tempData.reviewed) const reviewAction = useAppSelector(state => state.env.reviewAction) const reviewActions = useAppSelector(state => state.env.tempData.reviewActions) - + const {sendExtension} = useMessage() /** * 获取下一个需要翻译的行 * 会检测冷却 diff --git a/src/inject/inject.ts b/src/inject/inject.ts index 6817496..7c3a2ca 100644 --- a/src/inject/inject.ts +++ b/src/inject/inject.ts @@ -1,6 +1,6 @@ import { TOTAL_HEIGHT_DEF, HEADER_HEIGHT, TOTAL_HEIGHT_MIN, TOTAL_HEIGHT_MAX, IFRAME_ID, MESSAGE_TO_INJECT_DOWNLOAD_AUDIO, MESSAGE_TARGET_INJECT, MESSAGE_TO_APP_SET_INFOS } from '@/const' -import { PostMessagePayload, PostMessageResponse, startListening } from 'postmessage-promise' -import {MESSAGE_TARGET_EXTENSION, MESSAGE_TO_INJECT_FOLD, MESSAGE_TO_INJECT_MOVE, MESSAGE_TO_APP_SET_VIDEO_INFO, MESSAGE_TO_INJECT_GET_SUBTITLE, MESSAGE_TO_INJECT_GET_VIDEO_STATUS, MESSAGE_TO_INJECT_GET_VIDEO_ELEMENT_INFO, MESSAGE_TO_INJECT_UPDATETRANSRESULT, MESSAGE_TO_INJECT_PLAY, MESSAGE_TO_INJECT_HIDE_TRANS, MESSAGE_TO_INJECT_REFRESH_VIDEO_INFO} from '@/const' +import { MESSAGE_TO_INJECT_FOLD, MESSAGE_TO_INJECT_MOVE, MESSAGE_TO_APP_SET_VIDEO_INFO, MESSAGE_TO_INJECT_GET_SUBTITLE, MESSAGE_TO_INJECT_GET_VIDEO_STATUS, MESSAGE_TO_INJECT_GET_VIDEO_ELEMENT_INFO, MESSAGE_TO_INJECT_UPDATETRANSRESULT, MESSAGE_TO_INJECT_PLAY, MESSAGE_TO_INJECT_HIDE_TRANS, MESSAGE_TO_INJECT_REFRESH_VIDEO_INFO} from '@/const' +import InjectMessage from '@/messaging/injectMessage' const debug = (...args: any[]) => { console.debug('[Inject]', ...args) @@ -14,7 +14,7 @@ const debug = (...args: any[]) => { } const runtime: { - postMessageToApp?: (method: string, payload: PostMessagePayload) => Promise + injectMessage: InjectMessage // lastV?: string | null // lastVideoInfo?: VideoInfo @@ -26,40 +26,12 @@ const debug = (...args: any[]) => { showTrans: boolean curTrans?: string } = { + injectMessage: new InjectMessage(), fold: true, videoElementHeight: TOTAL_HEIGHT_DEF, showTrans: false, } - const sendExtension = async (method: string, params?: any) => { - return await chrome.runtime.sendMessage({ - target: MESSAGE_TARGET_EXTENSION, - method, - params: params??{}, - }).then((messageResult) => { - if (messageResult.success) { - return messageResult.data as T - } else { - throw new Error(messageResult.message) - } - }) - } - - const sendApp = async (method: string, params: any) => { - if (runtime.postMessageToApp != null) { - const messageResult = await runtime.postMessageToApp(method, params) as MessageResult | undefined - if (messageResult != null) { - if (messageResult.success) { - return messageResult.data as T - } else { - throw new Error(messageResult.message) - } - } else { - throw new Error('no response') - } - } - } - const getVideoElement = () => { const videoWrapper = document.getElementById('bilibili-player') return videoWrapper?.querySelector('video') as HTMLVideoElement | undefined @@ -179,7 +151,7 @@ const debug = (...args: any[]) => { debug('refreshVideoInfo: ', aid, cid, pages, subtitles) //send setVideoInfo - sendApp(MESSAGE_TO_APP_SET_VIDEO_INFO, { + runtime.injectMessage.sendApp(MESSAGE_TO_APP_SET_VIDEO_INFO, { url: location.origin + location.pathname, title, aid, @@ -214,7 +186,7 @@ const debug = (...args: any[]) => { .then(res => res.json()) .then(res => { // console.log('refreshSubtitles: ', aid, cid, res) - sendApp(MESSAGE_TO_APP_SET_INFOS, { + runtime.injectMessage.sendApp(MESSAGE_TO_APP_SET_INFOS, { infos: res.data.subtitle.subtitles }) }) @@ -333,73 +305,8 @@ const debug = (...args: any[]) => { }, } - /** - * @param sendResponse No matter what is returned, this method will definitely be called. - */ - const messageHandler = (event: MessageData, sender: chrome.runtime.MessageSender | null, sendResponse: (response?: MessageResult) => void) => { - const source = sender != null?((sender.tab != null) ? `tab ${sender.tab.url ?? ''}` : 'extension'):'app' - debug(`${source} => `, JSON.stringify(event)) - - // check event target - if (event.target !== MESSAGE_TARGET_INJECT) return - - const method = methods[event.method] - if (method != null) { - method(event.params, { - event, - sender, - }).then(data => { - // debug(`${source} <= `, event.method, JSON.stringify(data)) - return data - }).then(data => sendResponse({ - success: true, - code: 200, - data, - })).catch(err => { - console.error(err) - let message - if (err instanceof Error) { - message = err.message - } else if (typeof err === 'string') { - message = err - } else { - message = 'error: ' + JSON.stringify(err) - } - sendResponse({ - success: false, - code: 500, - message, - }) - }) - return true - } else { - console.error('Unknown method:', event.method) - sendResponse({ - success: false, - code: 501, - message: 'Unknown method: ' + event.method, - }) - } - } - - // listen message from app - startListening({}).then(e => { - const { postMessage, listenMessage, destroy } = e - runtime.postMessageToApp = postMessage - listenMessage((method, params, sendResponse) => { - messageHandler({ - target: MESSAGE_TARGET_INJECT, - method, - params, - }, null, sendResponse) - }) - }).catch(console.error) - - /** - * listen message from extension - * Attention: return true if you need to sendResponse asynchronously - */ - chrome.runtime.onMessage.addListener(messageHandler) + // 初始化injectMessage + runtime.injectMessage.init(methods) setInterval(() => { refreshVideoInfo().catch(console.error) diff --git a/src/messaging/ExtensionMessage.ts b/src/messaging/ExtensionMessage.ts new file mode 100644 index 0000000..150eb09 --- /dev/null +++ b/src/messaging/ExtensionMessage.ts @@ -0,0 +1,79 @@ +import { MESSAGE_TARGET_EXTENSION } from '@/const' + +class ExtensionMessage { + methods?: { + [key: string]: (params: any, context: MethodContext) => Promise + } + + debug = (...args: any[]) => { + console.debug('[Extension Messaging]', ...args) + } + + init = (methods: { + [key: string]: (params: any, context: MethodContext) => Promise + }) => { + this.methods = methods + + /** + * Note: Return true when sending a response asynchronously. + */ + chrome.runtime.onMessage.addListener((event: MessageData, sender: chrome.runtime.MessageSender, sendResponse: (result: any) => void) => { + this.debug((sender.tab != null) ? `tab ${sender.tab.url ?? ''} => ` : 'extension => ', event) + + // check event target + if (event.target !== MESSAGE_TARGET_EXTENSION) return + + const method = this.methods?.[event.method] + if (method != null) { + method(event.params, { + event, + sender, + }).then(data => sendResponse({ + success: true, + code: 200, + data, + })).catch(err => { + console.error(err) + let message + if (err instanceof Error) { + message = err.message + } else if (typeof err === 'string') { + message = err + } else { + message = 'error: ' + JSON.stringify(err) + } + sendResponse({ + success: false, + code: 500, + message, + }) + }) + return true + } else { + console.error('Unknown method:', event.method) + sendResponse({ + success: false, + code: 501, + message: 'Unknown method: ' + event.method, + }) + } + }) + } + + broadcastMessage = async (ignoreTabIds: number[] | undefined | null, target: string, method: string, params?: any) => { + const tabs = await chrome.tabs.query({ + discarded: false, + }) + for (const tab of tabs) { + try { + if (tab.id && ((ignoreTabIds == null) || !ignoreTabIds.includes(tab.id))) { + await chrome.tabs.sendMessage(tab.id, {target, method, params}) + } + } catch (e) { + console.error('send message to tab error', tab.id, e) + } + } + } +} + +export default ExtensionMessage \ No newline at end of file diff --git a/src/messaging/InjectMessage.ts b/src/messaging/InjectMessage.ts new file mode 100644 index 0000000..132484a --- /dev/null +++ b/src/messaging/InjectMessage.ts @@ -0,0 +1,121 @@ +import { MESSAGE_TARGET_EXTENSION, MESSAGE_TARGET_INJECT } from '@/const' +import { PostMessagePayload, PostMessageResponse, startListening } from 'postmessage-promise' + +class InjectMessage { + //类实例 + methods?: { + [key: string]: (params: any, context: MethodContext) => Promise + } + postMessageToApp?: (method: string, payload: PostMessagePayload) => Promise + + debug = (...args: any[]) => { + console.debug('[Inject Messaging]', ...args) + } + + /** + * @param sendResponse No matter what is returned, this method will definitely be called. + */ + messageHandler = (event: MessageData, sender: chrome.runtime.MessageSender | null, sendResponse: (response?: MessageResult) => void) => { + const source = sender != null ? ((sender.tab != null) ? `tab ${sender.tab.url ?? ''}` : 'extension') : 'app' + this.debug(`${source} => `, JSON.stringify(event)) + + // check event target + if (event.target !== MESSAGE_TARGET_INJECT) return + + const method = this.methods?.[event.method] + if (method != null) { + method(event.params, { + event, + sender, + }).then(data => { + // debug(`${source} <= `, event.method, JSON.stringify(data)) + return data + }).then(data => sendResponse({ + success: true, + code: 200, + data, + })).catch(err => { + console.error(err) + let message + if (err instanceof Error) { + message = err.message + } else if (typeof err === 'string') { + message = err + } else { + message = 'error: ' + JSON.stringify(err) + } + sendResponse({ + success: false, + code: 500, + message, + }) + }) + return true + } else { + console.error('Unknown method:', event.method) + sendResponse({ + success: false, + code: 501, + message: 'Unknown method: ' + event.method, + }) + } + } + + init(methods: { + [key: string]: (params: any, context: MethodContext) => Promise + }) { + this.methods = methods + // listen message from app + startListening({}).then(e => { + const { postMessage, listenMessage, destroy } = e + this.postMessageToApp = postMessage + listenMessage((method, params, sendResponse) => { + this.messageHandler({ + target: MESSAGE_TARGET_INJECT, + method, + params, + }, null, sendResponse) + }) + }).catch(console.error) + + /** + * listen message from extension + * Attention: return true if you need to sendResponse asynchronously + */ + chrome.runtime.onMessage.addListener(this.messageHandler) + } + + sendExtension = async (method: string, params?: any): Promise => { + return await chrome.runtime.sendMessage({ + target: MESSAGE_TARGET_EXTENSION, + method, + params: params ?? {}, + }).then((messageResult) => { + if (messageResult.success) { + return messageResult.data as T + } else { + throw new Error(messageResult.message) + } + }) + } + + sendApp = async (method: string, params: any): Promise => { + if (this.postMessageToApp != null) { + const messageResult = await this.postMessageToApp(method, params) as MessageResult | undefined + if (messageResult != null) { + if (messageResult.success) { + return messageResult.data as T + } else { + throw new Error(messageResult.message) + } + } else { + throw new Error('no response') + } + } else { + throw new Error('error: postMessageToApp is not initialized') + } + } + +} + +export default InjectMessage \ No newline at end of file diff --git a/src/messaging/useMessage.ts b/src/messaging/useMessage.ts new file mode 100644 index 0000000..b021206 --- /dev/null +++ b/src/messaging/useMessage.ts @@ -0,0 +1,42 @@ +import { MESSAGE_TARGET_EXTENSION } from '@/const' +import { injectWaiter } from './useMessageService' +import { useCallback } from 'react' + +const useMessage = () => { + const sendExtension = useCallback(async (method: string, params?: any) => { + return await chrome.runtime.sendMessage({ + target: MESSAGE_TARGET_EXTENSION, + method, + params: params ?? {}, + }).then((messageResult) => { + if (messageResult.success) { + return messageResult.data as T + } else { + throw new Error(messageResult.message) + } + }) + }, []) + + const sendInject = useCallback(async (method: string, params?: any) => { + // wait + const postInjectMessage = await injectWaiter.wait() + // send message + const messageResult = await postInjectMessage(method, params) as MessageResult | undefined + if (messageResult != null) { + if (messageResult.success) { + return messageResult.data as T + } else { + throw new Error(messageResult.message) + } + } else { + throw new Error('no response') + } + }, []) + + return { + sendExtension, + sendInject + } +} + +export default useMessage \ No newline at end of file diff --git a/src/hooks/useMessageService.ts b/src/messaging/useMessageService.ts similarity index 67% rename from src/hooks/useMessageService.ts rename to src/messaging/useMessageService.ts index 7138ed2..82f8ae8 100644 --- a/src/hooks/useMessageService.ts +++ b/src/messaging/useMessageService.ts @@ -1,16 +1,15 @@ -import {useCallback, useContext, useEffect} from 'react' +import {useCallback, useEffect} from 'react' import { MESSAGE_TARGET_APP, MESSAGE_TARGET_EXTENSION, MESSAGE_TARGET_INJECT, - MESSAGE_TO_APP_SET_INFOS, - MESSAGE_TO_APP_SET_VIDEO_INFO, } from '@/const' -import {debug} from '@/util/biz_util' import {callServer, PostMessagePayload, PostMessageResponse} from 'postmessage-promise' -import {useAppDispatch} from '../hooks/redux' import {Waiter} from '@kky002/kky-util' -import {setInfos, setTitle, setUrl, setCurInfo, setCurFetched, setData} from '@/redux/envReducer' + +const debug = (...args: any[]) => { + console.debug('[App Messaging]', ...args) +} let postInjectMessage: (method: string, params: PostMessagePayload) => Promise | undefined @@ -19,35 +18,21 @@ export const injectWaiter = new Waiter(() => ({ data: postInjectMessage }), 100, 15000) -const useMessageService = () => { - const dispatch = useAppDispatch() - const path = 'app' //useAppSelector(state => state.env.path) - +const useMessageService = (methods?: { + [key: string]: (params: any, from: string, context: MethodContext) => boolean +}) => { const messageHandler = useCallback((method: string, params: any, from: string, context: any): boolean => { - switch (method) { - case MESSAGE_TO_APP_SET_INFOS: - dispatch(setInfos(params.infos)) - dispatch(setCurInfo(undefined)) - dispatch(setCurFetched(false)) - dispatch(setData(undefined)) - break - case MESSAGE_TO_APP_SET_VIDEO_INFO: - dispatch(setInfos(params.infos)) - dispatch(setUrl(params.url)) - dispatch(setTitle(params.title)) - console.debug('video title: ', params.title) - break - default: - debug('unknown message method: ', method) - return false + const handler = methods?.[method] + if (handler != null) { + return handler(params, from, context) + }else { + debug('unknown message method: ', method) + return false } - return true - }, [dispatch]) + }, [methods]) // connect to inject useEffect(() => { - if (path !== 'app') return - let destroyFunc: (() => void) | undefined const serverObject = { @@ -76,7 +61,7 @@ const useMessageService = () => { return () => { destroyFunc?.() } - }, [messageHandler, path]) + }, [messageHandler]) const extensionMessageCallback = useCallback((event: MessageData, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => { debug((sender.tab != null) ? `tab ${sender.tab.url??''} => ` : 'extension => ', JSON.stringify(event)) diff --git a/src/util/biz_util.ts b/src/util/biz_util.ts index 2982b15..e3a5acb 100644 --- a/src/util/biz_util.ts +++ b/src/util/biz_util.ts @@ -2,43 +2,11 @@ import {APP_DOM_ID, CUSTOM_MODEL_TOKENS, MODEL_DEFAULT, MODEL_MAP, SUMMARIZE_TYP import {isDarkMode} from '@kky002/kky-util' import toast from 'react-hot-toast' import {findIndex} from 'lodash-es' -import {MESSAGE_TARGET_EXTENSION} from '../const' -import {injectWaiter} from '../hooks/useMessageService' export const debug = (...args: any[]) => { console.debug('[APP]', ...args) } -export const sendExtension = async (method: string, params?: any) => { - return await chrome.runtime.sendMessage({ - target: MESSAGE_TARGET_EXTENSION, - method, - params: params??{}, - }).then((messageResult) => { - if (messageResult.success) { - return messageResult.data as T - } else { - throw new Error(messageResult.message) - } - }) -} - -export const sendInject = async (method: string, params?: any) => { - // wait - const postInjectMessage = await injectWaiter.wait() - // send message - const messageResult = await postInjectMessage(method, params) as MessageResult | undefined - if (messageResult != null) { - if (messageResult.success) { - return messageResult.data as T - } else { - throw new Error(messageResult.message) - } - } else { - throw new Error('no response') - } -} - /** * 获取译文 */