Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.

Commit c26cf83

Browse files
committed
feat: keyboard shortcuts
1 parent b96d96b commit c26cf83

File tree

9 files changed

+133
-38
lines changed

9 files changed

+133
-38
lines changed

src/components/IconButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const IconButton = forwardRef(function IconButton(
2929
onClick={handleClick}
3030
css={tw`
3131
inline-flex justify-center items-center w-auto h-auto m-0 p-2
32-
cursor-pointer text-center no-underline rounded-md
32+
cursor-pointer text-center text-gray-800 no-underline rounded-md
3333
border border-solid border-gray-800 bg-white hover:bg-gray-100 active:bg-gray-200
3434
transition-colors ease-in-out duration-150
3535
`}>

src/manifest.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@
3131
"icon-128.png",
3232
"icon-34.png"
3333
],
34+
"commands": {
35+
"open_application": {
36+
"description": "Open application",
37+
"suggested_key": {
38+
"default": "Ctrl+Shift+W",
39+
"mac": "MacCtrl+Command+W"
40+
}
41+
},
42+
"toggle_ocr": {
43+
"description": "Toggle OCR",
44+
"suggested_key": {
45+
"default": "Ctrl+Shift+E",
46+
"mac": "MacCtrl+Command+E"
47+
}
48+
}
49+
},
3450
"manifest_version": 2,
3551
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
3652
}

src/pages/Background/common/utils.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,3 @@
1-
import { data } from 'autoprefixer'
2-
import cc from 'chrome-call'
3-
import { createClient } from 'connect.io'
4-
5-
import logger from '../../../common/logger'
6-
7-
export const openExtension = (): void => {
8-
cc(chrome.tabs, 'query', { active: true, currentWindow: true })
9-
.then((tabs: chrome.tabs.Tab[]) => {
10-
const client = createClient(tabs[0].id)
11-
12-
client.send('open_extension')
13-
})
14-
.catch((err) => {
15-
logger.error({
16-
err,
17-
})
18-
})
19-
}
20-
211
export const cropImage = async (
222
dataUrl: string,
233
config: {

src/pages/Background/index.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,51 @@
11
import '../../assets/img/icon-34.png'
22
import '../../assets/img/icon-128.png'
33

4+
import cc from 'chrome-call'
5+
import { createClient } from 'connect.io'
6+
47
import './common/server'
5-
import { openExtension } from './common/utils'
8+
import logger from '../../common/logger'
9+
10+
const openExtension = (): void => {
11+
cc(chrome.tabs, 'query', { active: true, currentWindow: true })
12+
.then((tabs: chrome.tabs.Tab[]) => {
13+
const client = createClient(tabs[0].id)
14+
15+
client.send('open_extension')
16+
})
17+
.catch((err) => {
18+
logger.error({
19+
err,
20+
})
21+
})
22+
}
23+
24+
const toggleOCR = (): void => {
25+
cc(chrome.tabs, 'query', { active: true, currentWindow: true })
26+
.then((tabs: chrome.tabs.Tab[]) => {
27+
const client = createClient(tabs[0].id)
28+
29+
client.send('toggle_ocr')
30+
})
31+
.catch((err) => {
32+
logger.error({
33+
err,
34+
})
35+
})
36+
}
637

738
chrome.browserAction.onClicked.addListener(openExtension)
39+
40+
chrome.commands.onCommand.addListener(function (command) {
41+
switch (command) {
42+
case 'open_application':
43+
openExtension()
44+
break
45+
case 'toggle_ocr':
46+
toggleOCR()
47+
break
48+
default:
49+
// no default
50+
}
51+
})

src/pages/Content/common/translation-stack.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { TranslateJob } from './types'
1+
import { AllJobTypes } from './types'
22

33
class TranslationStack {
4-
stack: Array<TranslateJob> = []
5-
onPush?: (job: TranslateJob) => void
4+
stack: Array<AllJobTypes> = []
5+
onPush?: (job: AllJobTypes) => void
66

7-
attachQueue(onPush: (job: TranslateJob) => void) {
7+
attachQueue(onPush: (job: AllJobTypes) => void) {
88
this.onPush = onPush
99

1010
while (this.stack.length) {
@@ -17,7 +17,7 @@ class TranslationStack {
1717
this.onPush = undefined
1818
}
1919

20-
push(job: TranslateJob) {
20+
push(job: AllJobTypes) {
2121
if (this.onPush) {
2222
this.onPush(job)
2323
} else {

src/pages/Content/common/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@ export interface TextSelection {
1010
}
1111

1212
export interface TranslateJob {
13+
type: 'translate'
1314
id: string
1415
text: string
1516
anchorId?: string
1617
sourceLang?: string
1718
}
19+
20+
export interface DirectiveJob {
21+
type: 'directive'
22+
directive: string
23+
payload?: Record<string, any>
24+
}
25+
26+
export type AllJobTypes = TranslateJob | DirectiveJob

src/pages/Content/components/App/index.tsx

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import CloseIcon from '../../../../components/svg/Close'
1515
import CursorClick from '../../../../components/svg/CursorClick'
1616
import LoadingCircle from '../../../../components/svg/LoadingCircle'
1717
import translationStack from '../../common/translation-stack'
18-
import { TranslateJob } from '../../common/types'
18+
import { AllJobTypes, DirectiveJob } from '../../common/types'
1919
import { ConfigContext, ConfigState } from '../../providers/config'
2020
import { useTranslateJobsDispatch } from '../../providers/translate-jobs'
2121
import OCRTool, { OnFinish } from '../OCRTool'
@@ -48,22 +48,46 @@ const App: React.FC = () => {
4848
}, [])
4949

5050
const onNewJob = useCallback(
51-
(job: TranslateJob) => {
51+
(job: AllJobTypes) => {
5252
logger.debug({
5353
msg: 'new job',
5454
job,
5555
})
5656

57-
if (!job.sourceLang) {
58-
job.sourceLang = 'EN'
57+
const doDirectiveJob = (job: DirectiveJob): void => {
58+
switch (job.directive) {
59+
case 'toggle_ocr':
60+
if (enableOCR) {
61+
setShowOCRTool((oldVal) => !oldVal)
62+
} else {
63+
enqueueSnackbar('无法开启 OCR,请确认已正确设置腾讯云 OCR', {
64+
variant: 'warning',
65+
})
66+
}
67+
break
68+
default:
69+
// no default
70+
}
5971
}
6072

61-
dispatch({
62-
type: 'add',
63-
payload: job,
64-
})
73+
switch (job.type) {
74+
case 'translate':
75+
if (!job.sourceLang) {
76+
job.sourceLang = 'EN'
77+
}
78+
79+
dispatch({
80+
type: 'add',
81+
payload: job,
82+
})
83+
break
84+
85+
case 'directive':
86+
doDirectiveJob(job)
87+
break
88+
}
6589
},
66-
[dispatch],
90+
[dispatch, enableOCR, enqueueSnackbar],
6791
)
6892

6993
const onDragStart: DraggableEventHandler = useCallback((e) => {
@@ -104,6 +128,7 @@ const App: React.FC = () => {
104128
})
105129
.then((result: string[]) => {
106130
translationStack.push({
131+
type: 'translate',
107132
id: uuid(),
108133
text: result.join('\n'),
109134
})
@@ -114,7 +139,7 @@ const App: React.FC = () => {
114139
.finally(() => {
115140
setLoadingOCR(false)
116141
})
117-
}, 100)
142+
}, 50)
118143
},
119144
[enqueueSnackbar],
120145
)
@@ -168,6 +193,7 @@ const App: React.FC = () => {
168193
<span tw="flex space-x-3">
169194
{enableOCR ? (
170195
<IconButton
196+
title="开启 OCR 识别"
171197
ref={ocrToolButtonRef}
172198
tw="p-1 text-gray-800"
173199
onClick={() => !loadingOCR && setShowOCRTool(true)}>
@@ -184,6 +210,7 @@ const App: React.FC = () => {
184210
) : undefined}
185211

186212
<IconButton
213+
title="关闭"
187214
ref={closeButtonRef}
188215
tw="p-1 text-gray-800"
189216
onClick={() => setClose(true)}>

src/pages/Content/components/TranslationItem/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ const TranslationItem: React.FC<{
174174
<div tw="h-full">
175175
{config ? (
176176
<select
177-
tw="px-2 py-0 h-full rounded-md truncate border-none bg-blue-50 text-gray-800"
177+
tw="px-2 py-0 h-full rounded-md truncate border-none bg-blue-50 text-gray-800 text-base text-base"
178178
css={css`
179179
width: 100px;
180180
`}

src/pages/Content/index.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const onMouseUp = (e: MouseEvent) => {
9797
highlightSelection(lastSelection.selection)
9898

9999
addTranslateJob({
100+
type: 'translate',
100101
anchorId,
101102
id,
102103
text: lastSelection.text,
@@ -162,6 +163,24 @@ const attachListeners = () => {
162163
client.on('open_extension', () => {
163164
initApp()
164165
})
166+
167+
client.on('toggle_ocr', () => {
168+
if (isAppAttached) {
169+
initApp()
170+
translationStack.push({
171+
type: 'directive',
172+
directive: 'toggle_ocr',
173+
})
174+
} else {
175+
initApp()
176+
setTimeout(() => {
177+
translationStack.push({
178+
type: 'directive',
179+
directive: 'toggle_ocr',
180+
})
181+
}, 50)
182+
}
183+
})
165184
})
166185
}
167186

0 commit comments

Comments
 (0)