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')
- }
-}
-
/**
* 获取译文
*/