Skip to content

Commit

Permalink
feat: Add Youdao
Browse files Browse the repository at this point in the history
  • Loading branch information
Pylogmon committed Sep 5, 2023
1 parent a58377a commit a22709f
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/i18n/locales/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@
"niutrans": {
"title": "NiuTrans",
"apikey": "API Key"
},
"youdao": {
"title": "Youdao",
"appkey": "App ID",
"key": "Key"
}
},
"recognize": {
Expand Down
5 changes: 5 additions & 0 deletions src/i18n/locales/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@
"niutrans": {
"title": "小牛翻译",
"apikey": "API Key"
},
"youdao": {
"title": "有道翻译",
"appkey": "App ID",
"key": "Key"
}
},
"recognize": {
Expand Down
1 change: 1 addition & 0 deletions src/services/translate/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export * as baidu_field from './baidu_field';
export * as tencent from './tencent';
export * as volcengine from './volcengine';
export * as niutrans from './niutrans';
export * as youdao from './youdao';
96 changes: 96 additions & 0 deletions src/services/translate/youdao/Config.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Input, Button } from '@nextui-org/react';
import toast, { Toaster } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import { open } from '@tauri-apps/api/shell';
import React, { useState } from 'react';

import { useConfig } from '../../../hooks/useConfig';
import { useToastStyle } from '../../../hooks';
import { translate } from './index';
import { Language } from './index';

export function Config(props) {
const { updateServiceList, onClose } = props;
const [config, setConfig] = useConfig(
'youdao',
{
appkey: '',
key: '',
},
{ sync: false }
);
const [isLoading, setIsLoading] = useState(false);

const { t } = useTranslation();
const toastStyle = useToastStyle();

return (
config !== null && (
<>
<Toaster />
<div className={'config-item'}>
<h3 className='my-auto'>{t('services.help')}</h3>
<Button
onPress={() => {
open('https://pot-app.com/docs/tutorial/api/translate');
}}
>
{t('services.help')}
</Button>
</div>
<div className={'config-item'}>
<h3 className='my-auto'>{t('services.translate.youdao.appkey')}</h3>
<Input
value={config['appkey']}
variant='bordered'
className='max-w-[50%]'
onValueChange={(value) => {
setConfig({
...config,
appkey: value,
});
}}
/>
</div>
<div className={'config-item'}>
<h3 className='my-auto'>{t('services.translate.youdao.key')}</h3>
<Input
value={config['key']}
variant='bordered'
className='max-w-[50%]'
onValueChange={(value) => {
setConfig({
...config,
key: value,
});
}}
/>
</div>
<div>
<Button
isLoading={isLoading}
color='primary'
fullWidth
onPress={() => {
setIsLoading(true);
translate('hello', Language.auto, Language.zh_cn, { config }).then(
() => {
setIsLoading(false);
setConfig(config, true);
updateServiceList('youdao');
onClose();
},
(e) => {
setIsLoading(false);
toast.error(t('config.service.test_failed') + e.toString(), { style: toastStyle });
}
);
}}
>
{t('common.save')}
</Button>
</div>
</>
)
);
}
72 changes: 72 additions & 0 deletions src/services/translate/youdao/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { fetch } from '@tauri-apps/api/http';
import { store } from '../../../utils/store';
import CryptoJS from 'crypto-js';
import { nanoid } from 'nanoid';

export async function translate(text, from, to, options = {}) {
const { config } = options;

let translateConfig = (await store.get('youdao')) ?? {};
if (config !== undefined) {
translateConfig = config;
}

const { appkey, key } = translateConfig;

const url = 'https://openapi.youdao.com/api';
const curtime = String(Math.round(new Date().getTime() / 1000));
const salt = nanoid();
const str1 = appkey + truncate(text) + salt + curtime + key;
const sign = CryptoJS.SHA256(str1).toString(CryptoJS.enc.Hex);

let res = await fetch(url, {
method: 'GET',
query: {
q: text,
from: from,
to: to,
appKey: appkey,
salt: salt,
sign: sign,
signType: 'v3',
curtime: curtime,
},
});
if (res.ok) {
let result = res.data;

if (result['isWord']) {
// 后续在此处实现词典功能
if (result['translation']) {
let target = '';
for (let i of result['translation']) {
target += i + '\n';
}
return target.trim();
} else {
throw JSON.stringify(result);
}
} else {
if (result['translation']) {
let target = '';
for (let i of result['translation']) {
target += i + '\n';
}
return target.trim();
} else {
throw JSON.stringify(result);
}
}
} else {
throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`;
}
}

function truncate(q) {
var len = q.length;
if (len <= 20) return q;
return q.substring(0, 10) + len + q.substring(len - 10, len);
}

export * from './Config';
export * from './info';
30 changes: 30 additions & 0 deletions src/services/translate/youdao/info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const info = {
name: 'youdao',
icon: 'logo/youdao.svg',
};

export enum Language {
auto = 'auto',
zh_cn = 'zh-CHS',
zh_tw = 'zh-CHT',
yue = 'yue',
en = 'en',
ja = 'jp',
ko = 'kor',
fr = 'fra',
es = 'spa',
ru = 'ru',
de = 'de',
it = 'it',
tr = 'tr',
pt = 'pt',
pt_br = 'pt',
vi = 'vie',
id = 'id',
th = 'th',
ms = 'may',
ar = 'ar',
hi = 'hi',
mn_mo = 'mn',
km = 'km',
}
2 changes: 1 addition & 1 deletion src/window/Config/pages/Service/Collection/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function Collection(props) {

return (
<>
<Card className='h-[calc(100vh-120px)] overflow-y-auto p-5 flex justify-between'>
<Card className='h-[calc(100vh-140px)] overflow-y-auto p-5 flex justify-between'>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId='droppable'
Expand Down
2 changes: 1 addition & 1 deletion src/window/Config/pages/Service/Recognize/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default function Recognize(props) {
return (
<>
<Toaster />
<Card className='h-[calc(100vh-120px)] overflow-y-auto p-5 flex justify-between'>
<Card className='h-[calc(100vh-140px)] overflow-y-auto p-5 flex justify-between'>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId='droppable'
Expand Down
2 changes: 1 addition & 1 deletion src/window/Config/pages/Service/Translate/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function Translate(props) {
return (
<>
<Toaster />
<Card className='h-[calc(100vh-120px)] overflow-y-auto p-5 flex justify-between'>
<Card className='h-[calc(100vh-140px)] overflow-y-auto p-5 flex justify-between'>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId='droppable'
Expand Down
2 changes: 1 addition & 1 deletion src/window/Config/pages/Service/Tts/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function Tts(props) {
return (
<>
<Toaster />
<Card className='h-[calc(100vh-120px)] overflow-y-auto p-5 flex justify-between'>
<Card className='h-[calc(100vh-140px)] overflow-y-auto p-5 flex justify-between'>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId='droppable'
Expand Down
5 changes: 1 addition & 4 deletions src/window/Config/pages/Service/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,7 @@ export default function Service() {
}, []);
return (
pluginList !== null && (
<Tabs
// disabledKeys={['collection']}
className='flex justify-center max-h-[calc(100%-40px)] overflow-y-auto'
>
<Tabs className='flex justify-center max-h-[calc(100%-40px)] overflow-y-auto'>
<Tab
key='translate'
title={t(`config.service.translate`)}
Expand Down

0 comments on commit a22709f

Please sign in to comment.