This commit is contained in:
IndieKKY
2024-10-06 19:16:22 +08:00
parent 9bcf6ee48d
commit 2460b0b822
12 changed files with 32 additions and 25 deletions

View File

@@ -19,6 +19,7 @@ import {downloadText, openUrl} from '@kky002/kky-util'
import toast from 'react-hot-toast'
import {getSummarize} from '../utils/bizUtil'
import useMessaging from '../messaging/layer2/useMessaging'
import { useMessage } from '@/hooks/message'
interface Props {
placement: Placement
}
@@ -70,7 +71,7 @@ const MoreBtn = (props: Props) => {
const title = useAppSelector(state => state.env.title)
const curSummaryType = useAppSelector(state => state.env.tempData.curSummaryType)
const {sendInject} = useMessaging()
const {sendInject} = useMessage()
const downloadCallback = useCallback((download: boolean) => {
if (data == null) {

3
src/hooks/message.ts Normal file
View File

@@ -0,0 +1,3 @@
import useMessaging from "@/messaging/layer2/useMessaging";
export const useMessage = useMessaging<AllExtensionMessages, AllInjectMessages>

View File

@@ -1,13 +1,13 @@
import {useAppDispatch, useAppSelector} from './redux'
import React, {useCallback} from 'react'
import {setNeedScroll, setReviewAction, setTempData} from '../redux/envReducer'
import useMessaging from '../messaging/layer2/useMessaging'
import { useMessage } from './message'
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} = useMessaging()
const {sendInject} = useMessage()
const move = useCallback((time: number, togglePause: boolean) => {
sendInject('MOVE', {time, togglePause})

View File

@@ -20,6 +20,7 @@ import {EVENT_EXPAND, GEMINI_TOKENS, TOTAL_HEIGHT_MAX, TOTAL_HEIGHT_MIN, WORDS_M
import {useAsyncEffect, useInterval} from 'ahooks'
import {getModelMaxTokens, getWholeText} from '../utils/bizUtil'
import useMessaging from '../messaging/layer2/useMessaging'
import { useMessage } from './message'
/**
* Service是单例类似后端的服务概念
@@ -43,7 +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} = useMessaging()
const {sendInject} = useMessage()
//如果reviewActions达到15次则设置reviewed为false
useEffect(() => {

View File

@@ -30,6 +30,7 @@ import {useMemoizedFn} from 'ahooks/es'
import {extractJsonArray, extractJsonObject, getModel} from '../utils/bizUtil'
import {formatTime} from '../utils/util'
import useMessaging from '@/messaging/layer2/useMessaging'
import { useMessage } from './message'
const useTranslate = () => {
const dispatch = useAppDispatch()
const data = useAppSelector(state => state.env.data)
@@ -43,7 +44,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} = useMessaging()
const {sendExtension} = useMessage()
/**
* 获取下一个需要翻译的行
* 会检测冷却

View File

@@ -29,7 +29,7 @@ const debug = (...args: any[]) => {
}
const runtime: {
injectMessaging: InjectMessaging
injectMessaging: InjectMessaging<AllExtensionMessages, AllInjectMessages, AllAPPMessages>
// lastV?: string | null
// lastVideoInfo?: VideoInfo

View File

@@ -17,7 +17,7 @@ type L2MethodHandlers<M extends ExtensionMessage, L2ReqMsg, L2ResMsg> = {
[K in M['method']]: L2MethodHandler<M, K, L2ReqMsg, L2ResMsg>
}
class ExtensionMessaging<M extends ExtensionMessage> {
class ExtensionMessaging<M extends ExtensionMessage, AllInjectMessagesType extends InjectMessage, AllAPPMessagesType extends AppMessage> {
portIdToPort: Map<string, PortContext<L2ReqMsg, L2ResMsg>> = new Map()
methods?: L2MethodHandlers<M, L2ReqMsg, L2ResMsg>
@@ -98,7 +98,7 @@ class ExtensionMessaging<M extends ExtensionMessage> {
//tags 如果为null则不检查tags如果为空数组则不会发送消息
//返回:最后一个响应(因此如果只发送给一个tab则返回的是该tab的响应)
broadcastMessageExact = async <M extends AllInjectMessages | AllAPPMessages, K extends M['method']>(tabIds: number[], tags: string[] | null, method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
broadcastMessageExact = async <M extends AllInjectMessagesType | AllAPPMessagesType, K extends M['method']>(tabIds: number[], tags: string[] | null, method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
// 如果tags为空数组则不会发送消息
if (tags != null && tags.length === 0) {
return
@@ -121,7 +121,7 @@ class ExtensionMessaging<M extends ExtensionMessage> {
return res?.data
}
broadcastMessage = async <M extends AllInjectMessages | AllAPPMessages, K extends M['method']>(ignoreTabIds: number[] | undefined | null, tags: string[], method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
broadcastMessage = async <M extends AllInjectMessagesType | AllAPPMessagesType, K extends M['method']>(ignoreTabIds: number[] | undefined | null, tags: string[], method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
const tabs = await chrome.tabs.query({
discarded: false,
})

View File

@@ -1,12 +1,12 @@
import Layer1Protocol from '../layer1/Layer1Protocol'
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_HANDSHAKE, MESSAGE_TO_EXTENSION_ROUTE, TAG_TARGET_APP, TAG_TARGET_INJECT } from '../const'
class InjectMessaging {
class InjectMessaging<AllExtensionMessagesType extends ExtensionMessage, AllInjectMessagesType extends InjectMessage, AllAPPMessagesType extends AppMessage> {
port?: chrome.runtime.Port
l1protocol?: Layer1Protocol<L2ReqMsg, L2ResMsg>
//类实例
methods?: {
[K in AllInjectMessages['method']]: (params: Extract<AllInjectMessages, { method: K }>['params'], context: MethodContext) => Promise<any>
[K in AllInjectMessagesType['method']]: (params: Extract<AllInjectMessagesType, { method: K }>['params'], context: MethodContext) => Promise<any>
}
debug = (...args: any[]) => {
@@ -59,7 +59,7 @@ class InjectMessaging {
}
init(methods: {
[K in AllInjectMessages['method']]: (params: Extract<AllInjectMessages, { method: K }>['params'], context: MethodContext) => Promise<any>
[K in AllInjectMessagesType['method']]: (params: Extract<AllInjectMessagesType, { method: K }>['params'], context: MethodContext) => Promise<any>
}) {
this.methods = methods
this.port = chrome.runtime.connect(import.meta.env.VITE_EXTENSION_ID, {
@@ -76,7 +76,7 @@ class InjectMessaging {
})
}
sendExtension = async <M extends AllExtensionMessages | MessagingExtensionMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
sendExtension = async <M extends AllExtensionMessagesType | MessagingExtensionMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
return await this.l1protocol!.sendMessage({
from: 'inject',
method,
@@ -90,8 +90,8 @@ class InjectMessaging {
})
}
sendApp = async <M extends AllAPPMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
return this.sendExtension('ROUTE', {
sendApp = async <M extends AllAPPMessagesType, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
return this.sendExtension('ROUTE' as any, {
tags: [TAG_TARGET_APP],
method,
params,

View File

@@ -3,8 +3,8 @@ import { useCallback } from 'react'
import Layer1Protocol from '../layer1/Layer1Protocol'
import { L2ReqMsg, L2ResMsg, TAG_TARGET_INJECT } from '../const'
const useMessaging = () => {
const sendExtension = useCallback(async <M extends AllExtensionMessages | MessagingExtensionMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
const useMessaging = <AllExtensionMessagesType extends ExtensionMessage, AllInjectMessagesType extends InjectMessage>() => {
const sendExtension = useCallback(async <M extends AllExtensionMessagesType | MessagingExtensionMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
// wait
const pmh = await msgWaiter.wait() as Layer1Protocol<L2ReqMsg, L2ResMsg>
// send message
@@ -20,8 +20,8 @@ const useMessaging = () => {
}
}, [])
const sendInject = useCallback(async <M extends AllInjectMessages, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
return await sendExtension('ROUTE', {
const sendInject = useCallback(async <M extends AllInjectMessagesType, K extends M['method']>(method: K, params?: Extract<M, { method: K }>['params']): Promise<Extract<M, { method: K }>['return']> => {
return await sendExtension('ROUTE' as any, {
tags: [TAG_TARGET_INJECT],
method,
params: params ?? {},

View File

@@ -1,7 +1,7 @@
import { useCallback, useMemo } from 'react'
import { Waiter } from '@kky002/kky-util'
import Layer1Protocol from '../layer1/Layer1Protocol'
import { L2ReqMsg, L2ResMsg, MESSAGE_TO_EXTENSION_HANDSHAKE, TAG_TARGET_APP } from '../const'
import { L2ReqMsg, L2ResMsg, TAG_TARGET_APP } from '../const'
const debug = (...args: any[]) => {
console.debug('[App Messaging]', ...args)
@@ -16,8 +16,8 @@ export const msgWaiter = new Waiter<Layer1Protocol<L2ReqMsg, L2ResMsg>>(() => ({
data: l1protocol!,
}), 100, 15000)
const useMessagingService = (methods?: {
[K in AllAPPMessages['method']]: (params: Extract<AllAPPMessages, { method: K }>['params'], context: MethodContext) => Promise<any>
const useMessagingService = <AllAPPMessagesType extends AppMessage>(methods?: {
[K in AllAPPMessagesType['method']]: (params: Extract<AllAPPMessagesType, { method: K }>['params'], context: MethodContext) => Promise<any>
}) => {
const messageHandler = useCallback(async (req: L2ReqMsg): Promise<L2ResMsg> => {
debug(`[${req.from}] ${req.method}`, JSON.stringify(req))

View File

@@ -8,15 +8,15 @@ import {EventBusContext} from '../Router'
import useTranslateService from '../hooks/useTranslateService'
import {setTheme} from '../utils/bizUtil'
import useSearchService from '../hooks/useSearchService'
import useMessaging from '../messaging/layer2/useMessaging'
import {setFold} from '../redux/envReducer'
import { useMessage } from '@/hooks/message'
function App() {
const dispatch = useAppDispatch()
const fold = useAppSelector(state => state.env.fold)
const eventBus = useContext(EventBusContext)
const totalHeight = useAppSelector(state => state.env.totalHeight)
const {sendInject} = useMessaging()
const {sendInject} = useMessage()
const envData = useAppSelector(state => state.env.envData)
const foldCallback = useCallback(() => {

View File

@@ -27,6 +27,7 @@ import toast from 'react-hot-toast'
import {useBoolean, useEventTarget} from 'ahooks'
import {useEventChecked} from '@kky002/kky-hooks'
import useMessaging from '@/messaging/layer2/useMessaging'
import { useMessage } from '@/hooks/message'
const Section = (props: {
title: ShowElement
@@ -58,7 +59,7 @@ const FormItem = (props: {
const OptionsPage = () => {
const dispatch = useAppDispatch()
const envData = useAppSelector(state => state.env.envData)
const {sendExtension} = useMessaging()
const {sendExtension} = useMessage()
const {value: sidePanelValue, onChange: setSidePanelValue} = useEventChecked(envData.sidePanel)
const {value: autoInsertValue, onChange: setAutoInsertValue} = useEventChecked(!envData.manualInsert)
const {value: autoExpandValue, onChange: setAutoExpandValue} = useEventChecked(envData.autoExpand)