You've already forked bilibili-subtitle
分离设置页面
This commit is contained in:
49
src/App.tsx
49
src/App.tsx
@@ -1,47 +1,22 @@
|
||||
import React, {useCallback, useContext, useEffect, useMemo} from 'react'
|
||||
import React, {useCallback, 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 Header from './biz/Header'
|
||||
import Body from './biz/Body'
|
||||
import useSubtitleService from './hooks/useSubtitleService'
|
||||
import {setEnvData, setEnvReady, setTempData, setTempReady} from './redux/envReducer'
|
||||
import {cloneDeep} from 'lodash-es'
|
||||
import {EVENT_EXPAND, MESSAGE_TO_INJECT_FOLD, PAGE_MAIN, PAGE_SETTINGS, STORAGE_ENV, STORAGE_TEMP} from './const'
|
||||
import {EventBusContext} from './Router'
|
||||
import useTranslateService from './hooks/useTranslateService'
|
||||
import {STORAGE_ENV, STORAGE_TEMP} from './const'
|
||||
import Settings from './biz/Settings'
|
||||
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 useSearchService from './hooks/useSearchService'
|
||||
import useMessage from './messaging/useMessage'
|
||||
import useMessagingService from './hooks/useMessagingService'
|
||||
import MainPage from './pages/MainPage'
|
||||
|
||||
function App() {
|
||||
const dispatch = useAppDispatch()
|
||||
const envData = useAppSelector(state => state.env.envData)
|
||||
const tempData = useAppSelector(state => state.env.tempData)
|
||||
const fold = useAppSelector(state => state.env.fold)
|
||||
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))
|
||||
dispatch(setPage(PAGE_MAIN))
|
||||
sendInject(MESSAGE_TO_INJECT_FOLD, {fold: !fold})
|
||||
}, [dispatch, fold])
|
||||
|
||||
// handle event
|
||||
eventBus.useSubscription((event: any) => {
|
||||
if (event.type === EVENT_EXPAND) {
|
||||
if (fold) {
|
||||
foldCallback()
|
||||
}
|
||||
}
|
||||
})
|
||||
const path = useAppSelector(state => state.env.path)
|
||||
|
||||
// env数据
|
||||
const savedEnvData = useMemo(() => {
|
||||
@@ -73,18 +48,12 @@ function App() {
|
||||
}, [envData.theme])
|
||||
|
||||
// services
|
||||
useSubtitleService()
|
||||
useTranslateService()
|
||||
useSearchService()
|
||||
useMessagingService()
|
||||
|
||||
return <div className='select-none w-full' style={{
|
||||
height: fold?undefined:`${totalHeight}px`,
|
||||
}}>
|
||||
<Header foldCallback={foldCallback}/>
|
||||
{!fold && page === PAGE_MAIN && <Body/>}
|
||||
{!fold && page === PAGE_SETTINGS && <Settings/>}
|
||||
<Toaster position='bottom-center'/>
|
||||
return <div>
|
||||
<Toaster position={path === 'app'?'bottom-center':'top-center'}/>
|
||||
{path === 'app' && <MainPage/>}
|
||||
{path === 'options' && <Settings/>}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@@ -1,15 +1,19 @@
|
||||
import App from './App'
|
||||
import {useEventEmitter} from 'ahooks'
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useAppDispatch } from './hooks/redux'
|
||||
import { setPath } from './redux/envReducer'
|
||||
|
||||
export const EventBusContext = React.createContext<any>(null)
|
||||
|
||||
const map: { [key: string]: string } = {
|
||||
'/options.html': 'options',
|
||||
// '/close': 'close',
|
||||
}
|
||||
|
||||
const Router = () => {
|
||||
const path = map[window.location.pathname] ?? 'app'
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
if (path === 'close') {
|
||||
window.close()
|
||||
@@ -18,8 +22,12 @@ const Router = () => {
|
||||
// 事件总线
|
||||
const eventBus = useEventEmitter()
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(setPath(path as 'app' | 'options'))
|
||||
}, [dispatch, path])
|
||||
|
||||
return <EventBusContext.Provider value={eventBus}>
|
||||
{path === 'app' && <App/>}
|
||||
{(path === 'app' || path === 'options') && <App/>}
|
||||
</EventBusContext.Provider>
|
||||
}
|
||||
|
||||
|
@@ -2,9 +2,8 @@ import {AiOutlineCloseCircle, BsDashSquare, BsPlusSquare, FaQuestion} from 'reac
|
||||
import classNames from 'classnames'
|
||||
import Markdown from '../components/Markdown'
|
||||
import React, {useCallback} from 'react'
|
||||
import {delAskInfo, mergeAskInfo, setPage} from '../redux/envReducer'
|
||||
import {delAskInfo, mergeAskInfo} from '../redux/envReducer'
|
||||
import {useAppDispatch, useAppSelector} from '../hooks/redux'
|
||||
import {PAGE_SETTINGS} from '../const'
|
||||
import toast from 'react-hot-toast'
|
||||
import useTranslate from '../hooks/useTranslate'
|
||||
|
||||
@@ -25,7 +24,7 @@ const Ask = (props: {
|
||||
addAskTask(ask.id, segments[0], ask.question).catch(console.error)
|
||||
}
|
||||
} else {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
toast.error('需要先设置ApiKey!')
|
||||
}
|
||||
}, [addAskTask, ask.id, ask.question, dispatch, envData.aiType, envData.apiKey, envData.geminiApiKey, segments])
|
||||
|
@@ -7,7 +7,6 @@ import {
|
||||
setCheckAutoScroll,
|
||||
setFoldAll,
|
||||
setNeedScroll,
|
||||
setPage,
|
||||
setSearchText,
|
||||
setSegmentFold,
|
||||
setTempData
|
||||
@@ -104,7 +103,7 @@ const Body = () => {
|
||||
const onSummarizeAll = useCallback(() => {
|
||||
const apiKey = envData.aiType === 'gemini'?envData.geminiApiKey:envData.apiKey
|
||||
if (!apiKey) {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
toast.error('需要先设置ApiKey!')
|
||||
return
|
||||
}
|
||||
@@ -148,7 +147,7 @@ const Body = () => {
|
||||
if (apiKey) {
|
||||
dispatch(setAutoTranslate(!autoTranslate))
|
||||
} else {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
toast.error('需要先设置ApiKey!')
|
||||
}
|
||||
}, [autoTranslate, dispatch, envData.aiType, envData.apiKey, envData.geminiApiKey])
|
||||
@@ -197,7 +196,7 @@ const Body = () => {
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
toast.error('需要先设置ApiKey!')
|
||||
}
|
||||
}
|
||||
|
@@ -11,9 +11,9 @@ import {
|
||||
import Popover from '../components/Popover'
|
||||
import {Placement} from '@popperjs/core/lib/enums'
|
||||
import {useAppDispatch, useAppSelector} from '../hooks/redux'
|
||||
import {setEnvData, setPage, setTempData} from '../redux/envReducer'
|
||||
import {setEnvData, setTempData} from '../redux/envReducer'
|
||||
import {EventBusContext} from '../Router'
|
||||
import {EVENT_EXPAND, MESSAGE_TO_INJECT_DOWNLOAD_AUDIO, PAGE_SETTINGS} from '../const'
|
||||
import {EVENT_EXPAND, MESSAGE_TO_INJECT_DOWNLOAD_AUDIO} from '../const'
|
||||
import {formatSrtTime, formatTime, formatVttTime} from '../util/util'
|
||||
import {downloadText, openUrl} from '@kky002/kky-util'
|
||||
import toast from 'react-hot-toast'
|
||||
@@ -288,7 +288,7 @@ const MoreBtn = (props: Props) => {
|
||||
{/* </li> */}
|
||||
<li className='hover:bg-accent'>
|
||||
<a className='flex items-center' onClick={(e) => {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
setMoreVisible(false)
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import React, {MutableRefObject, useCallback, useEffect, useMemo, useRef} from 'react'
|
||||
import {useAppDispatch, useAppSelector} from '../hooks/redux'
|
||||
import {setFloatKeyPointsSegIdx, setPage, setSegmentFold, setTempData} from '../redux/envReducer'
|
||||
import {setFloatKeyPointsSegIdx, setSegmentFold, setTempData} from '../redux/envReducer'
|
||||
import classNames from 'classnames'
|
||||
import {FaClipboardList} from 'react-icons/fa'
|
||||
import {PAGE_MAIN, PAGE_SETTINGS, SUMMARIZE_THRESHOLD, SUMMARIZE_TYPES} from '../const'
|
||||
@@ -76,7 +76,7 @@ const Summarize = (props: {
|
||||
if (apiKey) {
|
||||
addSummarizeTask(curSummaryType, segment).catch(console.error)
|
||||
} else {
|
||||
dispatch(setPage(PAGE_SETTINGS))
|
||||
chrome.runtime.openOptionsPage()
|
||||
toast.error('需要先设置ApiKey!')
|
||||
}
|
||||
}, [addSummarizeTask, curSummaryType, dispatch, envData.aiType, envData.apiKey, envData.geminiApiKey, segment])
|
||||
@@ -145,7 +145,6 @@ const SegmentCard = (props: {
|
||||
const summarizeEnable = useAppSelector(state => state.env.envData.summarizeEnable)
|
||||
const summarizeFloat = useAppSelector(state => state.env.envData.summarizeFloat)
|
||||
const fold = useAppSelector(state => state.env.fold)
|
||||
const page = useAppSelector(state => state.env.page)
|
||||
const compact = useAppSelector(state => state.env.tempData.compact)
|
||||
const floatKeyPointsSegIdx = useAppSelector(state => state.env.floatKeyPointsSegIdx)
|
||||
const showCurrent = useMemo(() => curIdx != null && segment.startIdx <= curIdx && curIdx <= segment.endIdx, [curIdx, segment.endIdx, segment.startIdx])
|
||||
@@ -168,7 +167,7 @@ const SegmentCard = (props: {
|
||||
// 检测设置floatKeyPointsSegIdx
|
||||
useEffect(() => {
|
||||
if (summarizeFloat) { // 已启用
|
||||
if (!fold && page === PAGE_MAIN && showCurrent) { // 当前Card有控制权
|
||||
if (!fold && showCurrent) { // 当前Card有控制权
|
||||
if (!inViewport && (summary != null) && !isSummaryEmpty(summary)) {
|
||||
dispatch(setFloatKeyPointsSegIdx(segment.startIdx))
|
||||
} else {
|
||||
@@ -176,7 +175,7 @@ const SegmentCard = (props: {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [dispatch, fold, inViewport, page, segment.startIdx, showCurrent, summarizeFloat, summary])
|
||||
}, [dispatch, fold, inViewport, segment.startIdx, showCurrent, summarizeFloat, summary])
|
||||
|
||||
const onSelBrief = useCallback(() => {
|
||||
dispatch(setTempData({
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, {PropsWithChildren, useCallback, useMemo, useState} from 'react'
|
||||
import {setEnvData, setPage, setTempData} from '../redux/envReducer'
|
||||
import {setEnvData} from '../redux/envReducer'
|
||||
import {useAppDispatch, useAppSelector} from '../hooks/redux'
|
||||
import {
|
||||
ASK_ENABLED_DEFAULT,
|
||||
@@ -138,13 +138,16 @@ const Settings = () => {
|
||||
cnSearchEnabled: cnSearchEnabledValue,
|
||||
askEnabled: askEnabledValue,
|
||||
}))
|
||||
dispatch(setPage(PAGE_MAIN))
|
||||
toast.success('保存成功')
|
||||
// 3秒后关闭
|
||||
setTimeout(() => {
|
||||
window.close()
|
||||
}, 3000)
|
||||
}, [dispatch, autoExpandValue, aiTypeValue, apiKeyValue, serverUrlValue, modelValue, customModelValue, customModelTokensValue, geminiApiKeyValue, translateEnableValue, languageValue, hideOnDisableAutoTranslateValue, themeValue, transDisplayValue, summarizeEnableValue, summarizeFloatValue, summarizeLanguageValue, wordsValue, fetchAmountValue, fontSizeValue, promptsValue, searchEnabledValue, cnSearchEnabledValue, askEnabledValue])
|
||||
|
||||
const onCancel = useCallback(() => {
|
||||
dispatch(setPage(PAGE_MAIN))
|
||||
}, [dispatch])
|
||||
window.close()
|
||||
}, [])
|
||||
|
||||
const onFetchAmountChange = useCallback((e: any) => {
|
||||
setFetchAmountValue(parseInt(e.target.value))
|
||||
|
52
src/pages/MainPage.tsx
Normal file
52
src/pages/MainPage.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import React, {useCallback, useContext, useEffect, useMemo} from 'react'
|
||||
import {useAppDispatch, useAppSelector} from '../hooks/redux'
|
||||
import {setEnvData, setEnvReady, setFold, setTempData, setTempReady} 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 {EventBusContext} from '../Router'
|
||||
import useTranslateService from '../hooks/useTranslateService'
|
||||
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 useSearchService from '../hooks/useSearchService'
|
||||
import useMessage from '../messaging/useMessage'
|
||||
import useMessagingService from '../hooks/useMessagingService'
|
||||
|
||||
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} = useMessage()
|
||||
|
||||
const foldCallback = useCallback(() => {
|
||||
dispatch(setFold(!fold))
|
||||
sendInject(MESSAGE_TO_INJECT_FOLD, {fold: !fold})
|
||||
}, [dispatch, fold])
|
||||
|
||||
// handle event
|
||||
eventBus.useSubscription((event: any) => {
|
||||
if (event.type === EVENT_EXPAND) {
|
||||
if (fold) {
|
||||
foldCallback()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useSubtitleService()
|
||||
useTranslateService()
|
||||
useSearchService()
|
||||
|
||||
return <div className='select-none w-full' style={{
|
||||
height: fold?undefined:`${totalHeight}px`,
|
||||
}}>
|
||||
<Header foldCallback={foldCallback}/>
|
||||
{!fold && <Body/>}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default App
|
@@ -9,9 +9,10 @@ interface EnvState {
|
||||
tempData: TempData
|
||||
tempReady: boolean
|
||||
|
||||
path?: 'app' | 'options'
|
||||
|
||||
fold: boolean // fold app
|
||||
foldAll?: boolean // fold all segments
|
||||
page?: string
|
||||
autoTranslate?: boolean
|
||||
autoScroll?: boolean
|
||||
checkAutoScroll?: boolean
|
||||
@@ -103,6 +104,9 @@ export const slice = createSlice({
|
||||
setReviewAction: (state, action: PayloadAction<boolean>) => {
|
||||
state.reviewAction = action.payload
|
||||
},
|
||||
setPath: (state, action: PayloadAction<'app' | 'options' | undefined>) => {
|
||||
state.path = action.payload
|
||||
},
|
||||
setTempReady: (state) => {
|
||||
state.tempReady = true
|
||||
},
|
||||
@@ -118,9 +122,6 @@ export const slice = createSlice({
|
||||
setFoldAll: (state, action: PayloadAction<boolean>) => {
|
||||
state.foldAll = action.payload
|
||||
},
|
||||
setPage: (state, action: PayloadAction<string | undefined>) => {
|
||||
state.page = action.payload
|
||||
},
|
||||
setTotalHeight: (state, action: PayloadAction<number>) => {
|
||||
state.totalHeight = action.payload
|
||||
},
|
||||
@@ -298,6 +299,7 @@ export const slice = createSlice({
|
||||
})
|
||||
|
||||
export const {
|
||||
setPath,
|
||||
setUrl,
|
||||
setTempReady,
|
||||
setTempData,
|
||||
@@ -314,7 +316,6 @@ export const {
|
||||
setTitle,
|
||||
setSegments,
|
||||
setLastSummarizeTime,
|
||||
setPage,
|
||||
setLastTransTime,
|
||||
clearTransResults,
|
||||
addTransResults,
|
||||
|
Reference in New Issue
Block a user