Support DeepL API
This commit is contained in:
parent
a262963906
commit
cfcb01c93d
|
@ -50,6 +50,42 @@
|
||||||
"generalLabel": {
|
"generalLabel": {
|
||||||
"message": "General"
|
"message": "General"
|
||||||
},
|
},
|
||||||
|
"translationApiLabel": {
|
||||||
|
"message": "Translation engine"
|
||||||
|
},
|
||||||
|
"googleApiLabel": {
|
||||||
|
"message": "Google translate API"
|
||||||
|
},
|
||||||
|
"googleApiCaptionLabel": {
|
||||||
|
"message": "Use Google Translate API. No registration is required."
|
||||||
|
},
|
||||||
|
"deeplApiLabel": {
|
||||||
|
"message": "DeepL API"
|
||||||
|
},
|
||||||
|
"deeplApiCaptionLabel": {
|
||||||
|
"message": "Use DeepL API. You must register with DeepL API Free or DeepL API Pro to obtain an authorization key."
|
||||||
|
},
|
||||||
|
"howToUseDeeplLabel": {
|
||||||
|
"message": "How to register DeepL API"
|
||||||
|
},
|
||||||
|
"deeplPlanLabel": {
|
||||||
|
"message": "DeepL API plan"
|
||||||
|
},
|
||||||
|
"deeplPlanCaptionLabel": {
|
||||||
|
"message": "Select the DeepL API plan for which you registered."
|
||||||
|
},
|
||||||
|
"deeplFreeLabel": {
|
||||||
|
"message": "DeepL API Free"
|
||||||
|
},
|
||||||
|
"deeplProLabel": {
|
||||||
|
"message": "DeepL API Pro"
|
||||||
|
},
|
||||||
|
"deeplAuthKeyLabel": {
|
||||||
|
"message": "Authorization key"
|
||||||
|
},
|
||||||
|
"deeplAuthKeyCaptionLabel": {
|
||||||
|
"message": "Enter the authentication key for the DeepL API."
|
||||||
|
},
|
||||||
"targetLangCaptionLabel": {
|
"targetLangCaptionLabel": {
|
||||||
"message": "Select the default target language."
|
"message": "Select the default target language."
|
||||||
},
|
},
|
||||||
|
@ -383,6 +419,9 @@
|
||||||
"unavailableError": {
|
"unavailableError": {
|
||||||
"message": "Error: Service usage limit reached. Please wait a while and try again."
|
"message": "Error: Service usage limit reached. Please wait a while and try again."
|
||||||
},
|
},
|
||||||
|
"deeplAuthError": {
|
||||||
|
"message": "Error: Authentication of DeepL API failed. Please set the authentication key and plan correctly on the settings page."
|
||||||
|
},
|
||||||
"unknownError": {
|
"unknownError": {
|
||||||
"message": "Error: Unknown error"
|
"message": "Error: Unknown error"
|
||||||
},
|
},
|
||||||
|
@ -724,5 +763,20 @@
|
||||||
},
|
},
|
||||||
"lang_zu": {
|
"lang_zu": {
|
||||||
"message": "Zulu"
|
"message": "Zulu"
|
||||||
|
},
|
||||||
|
"lang_en-US": {
|
||||||
|
"message": "English (American)"
|
||||||
|
},
|
||||||
|
"lang_en-GB": {
|
||||||
|
"message": "English (British)"
|
||||||
|
},
|
||||||
|
"lang_pt-PT": {
|
||||||
|
"message": "Portuguese"
|
||||||
|
},
|
||||||
|
"lang_pt-BR": {
|
||||||
|
"message": "Portuguese (Brazilian)"
|
||||||
|
},
|
||||||
|
"lang_zh": {
|
||||||
|
"message": "Chinese"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,9 +2,11 @@ import browser from "webextension-polyfill";
|
||||||
const alphabeticallySort = (a, b) => a.name.localeCompare(b.name);
|
const alphabeticallySort = (a, b) => a.name.localeCompare(b.name);
|
||||||
|
|
||||||
const langListGoogle = ["af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jv", "kn", "kk", "km", "rw", "ko", "ku", "ky", "lo", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "or", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "tr", "tk", "uk", "ur", "ug", "uz", "vi", "cy", "xh", "yi", "yo", "zu"];
|
const langListGoogle = ["af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jv", "kn", "kk", "km", "rw", "ko", "ku", "ky", "lo", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "or", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "tr", "tk", "uk", "ur", "ug", "uz", "vi", "cy", "xh", "yi", "yo", "zu"];
|
||||||
|
const langListDeepl = ["bg", "cs", "da", "de", "el", "en-GB", "en-US", "es", "et", "fi", "fr", "hu", "it", "ja", "lt", "lv", "nl", "pl", "pt-PT", "pt-BR", "ro", "ru", "sk", "sl", "sv", "zh"];
|
||||||
|
|
||||||
export default () => {
|
export default (translationApi) => {
|
||||||
const langOptions = langListGoogle.map(lang => ({
|
const langList = translationApi === "google" ? langListGoogle : langListDeepl;
|
||||||
|
const langOptions = langList.map(lang => ({
|
||||||
value: lang,
|
value: lang,
|
||||||
name: browser.i18n.getMessage("lang_" + lang)
|
name: browser.i18n.getMessage("lang_" + lang)
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { getSettings } from "src/settings/settings";
|
||||||
|
|
||||||
let translationHistory = [];
|
let translationHistory = [];
|
||||||
|
|
||||||
const logDir = "common/translate";
|
const logDir = "common/translate";
|
||||||
|
|
||||||
const getHistory = (sourceWord, sourceLang, targetLang) => {
|
const getHistory = (sourceWord, sourceLang, targetLang, translationApi) => {
|
||||||
const history = translationHistory.find(
|
const history = translationHistory.find(
|
||||||
history =>
|
history =>
|
||||||
history.sourceWord == sourceWord &&
|
history.sourceWord == sourceWord &&
|
||||||
history.sourceLang == sourceLang &&
|
history.sourceLang == sourceLang &&
|
||||||
history.targetLang == targetLang &&
|
history.targetLang == targetLang &&
|
||||||
history.result.statusText == "OK"
|
history.translationApi == translationApi &&
|
||||||
|
!history.result.isError
|
||||||
);
|
);
|
||||||
return history;
|
return history;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setHistory = (sourceWord, sourceLang, targetLang, formattedResult) => {
|
const setHistory = (sourceWord, sourceLang, targetLang, translationApi, result) => {
|
||||||
translationHistory.push({
|
translationHistory.push({
|
||||||
sourceWord: sourceWord,
|
sourceWord: sourceWord,
|
||||||
sourceLang: sourceLang,
|
sourceLang: sourceLang,
|
||||||
targetLang: targetLang,
|
targetLang: targetLang,
|
||||||
result: formattedResult
|
translationApi: translationApi,
|
||||||
|
result: result
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendRequest = async (word, sourceLang, targetLang) => {
|
const sendRequestToGoogle = async (word, sourceLang, targetLang) => {
|
||||||
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&dt=bd&dj=1&q=${encodeURIComponent(
|
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&dt=bd&dj=1&q=${encodeURIComponent(
|
||||||
word
|
word
|
||||||
)}`;
|
)}`;
|
||||||
|
@ -64,24 +68,47 @@ const sendRequest = async (word, sourceLang, targetLang) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendRequestToDeepL = async (word, sourceLang, targetLang) => {
|
const sendRequestToDeepL = async (word, sourceLang, targetLang) => {
|
||||||
log.log(logDir, "sendRequestToDeepL()");
|
|
||||||
|
|
||||||
let params = new URLSearchParams();
|
let params = new URLSearchParams();
|
||||||
|
const authKey = getSettings("deeplAuthKey");
|
||||||
const key = "f5a2c02c-7871-af5c-0d6a-244a9e6d4a1f:fx";
|
params.append("auth_key", authKey);
|
||||||
params.append("auth_key", key);
|
|
||||||
params.append("text", word);
|
params.append("text", word);
|
||||||
params.append("target_lang", "ja");
|
params.append("target_lang", targetLang);
|
||||||
|
const url = getSettings("deeplPlan") === "deeplFree" ?
|
||||||
|
"https://api-free.deepl.com/v2/translate" :
|
||||||
|
"https://api.deepl.com/v2/translate";
|
||||||
|
const result = await axios.post(url, params).catch(e => e.response);
|
||||||
|
|
||||||
const url = "https://api-free.deepl.com/v2/translate";
|
const resultData = {
|
||||||
|
resultText: "",
|
||||||
|
candidateText: "",
|
||||||
|
sourceLanguage: "",
|
||||||
|
percentage: 0,
|
||||||
|
isError: false,
|
||||||
|
errorMessage: ""
|
||||||
|
};
|
||||||
|
|
||||||
const res = await axios.post(url, params).catch(e => e.response);
|
if (!result || result?.status !== 200) {
|
||||||
console.log("!!!!!!!!!!!!!!!", res);
|
resultData.isError = true;
|
||||||
|
|
||||||
|
if (!result || result.status === 0) resultData.errorMessage = browser.i18n.getMessage("networkError");
|
||||||
|
else if (result.status === 403) resultData.errorMessage = browser.i18n.getMessage("deeplAuthError");
|
||||||
|
else resultData.errorMessage = `${browser.i18n.getMessage("unknownError")} [${result?.status} ${result?.statusText}] ${result?.data.message}`;
|
||||||
|
|
||||||
|
log.error(logDir, "sendRequestToDeepL()", result);
|
||||||
|
return resultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
resultData.resultText = result.data.translations[0].text;
|
||||||
|
resultData.sourceLanguage = result.data.translations[0].detected_source_language.toLowerCase();
|
||||||
|
resultData.percentage = 1;
|
||||||
|
|
||||||
|
log.log(logDir, "sendRequestToDeepL()", resultData);
|
||||||
|
return resultData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default async (sourceWord, sourceLang = "auto", targetLang) => {
|
export default async (sourceWord, sourceLang = "auto", targetLang, translationApi) => {
|
||||||
log.log(logDir, "tranlate()", sourceWord, targetLang);
|
log.log(logDir, "tranlate()", sourceWord, targetLang, translationApi);
|
||||||
sourceWord = sourceWord.trim();
|
sourceWord = sourceWord.trim();
|
||||||
if (sourceWord === "")
|
if (sourceWord === "")
|
||||||
return {
|
return {
|
||||||
|
@ -95,7 +122,9 @@ export default async (sourceWord, sourceLang = "auto", targetLang) => {
|
||||||
const history = getHistory(sourceWord, sourceLang, targetLang);
|
const history = getHistory(sourceWord, sourceLang, targetLang);
|
||||||
if (history) return history.result;
|
if (history) return history.result;
|
||||||
|
|
||||||
const result = await sendRequest(sourceWord, sourceLang, targetLang);
|
const result = getSettings("translationApi") === "google" ?
|
||||||
setHistory(sourceWord, sourceLang, targetLang, result);
|
await sendRequestToGoogle(sourceWord, sourceLang, targetLang) :
|
||||||
|
await sendRequestToDeepL(sourceWord, sourceLang, targetLang);
|
||||||
|
setHistory(sourceWord, sourceLang, targetLang, translationApi, result);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ const matchesTargetLang = async selectedText => {
|
||||||
const isNotText = result.percentage === 0;
|
const isNotText = result.percentage === 0;
|
||||||
if (isNotText) return true;
|
if (isNotText) return true;
|
||||||
|
|
||||||
const matchsLangs = targetLang === result.sourceLanguage;
|
const matchsLangs = targetLang.split("-")[0] === result.sourceLanguage.split("-")[0]; // split("-")[0] : deepLでenとen-USを区別しないために必要
|
||||||
return matchsLangs;
|
return matchsLangs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ export default class TranslateContainer extends Component {
|
||||||
const secondLang = getSettings("secondTargetLang");
|
const secondLang = getSettings("secondTargetLang");
|
||||||
const shouldSwitchSecondLang =
|
const shouldSwitchSecondLang =
|
||||||
getSettings("ifChangeSecondLangOnPage") &&
|
getSettings("ifChangeSecondLangOnPage") &&
|
||||||
result.sourceLanguage === targetLang && result.percentage > 0 && targetLang !== secondLang;
|
result.sourceLanguage.split("-")[0] === targetLang.split("-")[0] && result.percentage > 0 && targetLang !== secondLang;
|
||||||
if (shouldSwitchSecondLang) result = await translateText(this.selectedText, secondLang);
|
if (shouldSwitchSecondLang) result = await translateText(this.selectedText, secondLang);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|
|
@ -18,6 +18,8 @@ export default props => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setSettings(id, value);
|
setSettings(id, value);
|
||||||
|
|
||||||
|
if (props.handleChange) props.handleChange();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCheckedChange = e => {
|
const handleCheckedChange = e => {
|
||||||
|
@ -113,8 +115,8 @@ export default props => {
|
||||||
formId = id;
|
formId = id;
|
||||||
optionForm = (
|
optionForm = (
|
||||||
<div className="selectWrap">
|
<div className="selectWrap">
|
||||||
<select id={formId} onChange={handleValueChange} defaultValue={currentValue}>
|
<select id={formId} onChange={handleValueChange} value={currentValue}>
|
||||||
{props.options.map((option, index) => (
|
{(typeof props.options === 'function' ? props.options() : props.options).map((option, index) => (
|
||||||
<option value={option.value} key={index}>
|
<option value={option.value} key={index}>
|
||||||
{props.useRawOptionName ? option.name : browser.i18n.getMessage(option.name)}
|
{props.useRawOptionName ? option.name : browser.i18n.getMessage(option.name)}
|
||||||
</option>
|
</option>
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import browser from "webextension-polyfill";
|
import browser from "webextension-polyfill";
|
||||||
import generateLangOptions from "src/common/generateLangOptions";
|
|
||||||
import openUrl from "src/common/openUrl";
|
import openUrl from "src/common/openUrl";
|
||||||
import "../styles/Footer.scss";
|
import "../styles/Footer.scss";
|
||||||
|
|
||||||
export default class Footer extends Component {
|
export default class Footer extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.langList = generateLangOptions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLinkClick = async () => {
|
handleLinkClick = async () => {
|
||||||
|
@ -23,7 +21,7 @@ export default class Footer extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { tabUrl, targetLang, langHistory } = this.props;
|
const { tabUrl, targetLang, langHistory, langList } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
@ -39,7 +37,7 @@ export default class Footer extends Component {
|
||||||
>
|
>
|
||||||
|
|
||||||
<optgroup label={browser.i18n.getMessage("recentLangLabel")}>
|
<optgroup label={browser.i18n.getMessage("recentLangLabel")}>
|
||||||
{this.langList.filter(option => langHistory.includes(option.value))
|
{langList.filter(option => langHistory.includes(option.value))
|
||||||
.map(option => (
|
.map(option => (
|
||||||
<option value={option.value} key={option.value}>
|
<option value={option.value} key={option.value}>
|
||||||
{option.name}
|
{option.name}
|
||||||
|
@ -47,7 +45,7 @@ export default class Footer extends Component {
|
||||||
))}
|
))}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label={browser.i18n.getMessage("allLangLabel")}>
|
<optgroup label={browser.i18n.getMessage("allLangLabel")}>
|
||||||
{this.langList.map(option => (
|
{langList.map(option => (
|
||||||
<option value={option.value} key={option.value}>
|
<option value={option.value} key={option.value}>
|
||||||
{option.name}
|
{option.name}
|
||||||
</option>
|
</option>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import log from "loglevel";
|
||||||
import { initSettings, getSettings, setSettings } from "src/settings/settings";
|
import { initSettings, getSettings, setSettings } from "src/settings/settings";
|
||||||
import { updateLogLevel, overWriteLogLevel } from "src/common/log";
|
import { updateLogLevel, overWriteLogLevel } from "src/common/log";
|
||||||
import translate from "src/common/translate";
|
import translate from "src/common/translate";
|
||||||
|
import generateLangOptions from "src/common/generateLangOptions";
|
||||||
import Header from "./Header";
|
import Header from "./Header";
|
||||||
import InputArea from "./InputArea";
|
import InputArea from "./InputArea";
|
||||||
import ResultArea from "./ResultArea";
|
import ResultArea from "./ResultArea";
|
||||||
|
@ -42,6 +43,7 @@ export default class PopupPage extends Component {
|
||||||
sourceLang: "",
|
sourceLang: "",
|
||||||
isError: false,
|
isError: false,
|
||||||
errorMessage: "",
|
errorMessage: "",
|
||||||
|
langList: [],
|
||||||
tabUrl: "",
|
tabUrl: "",
|
||||||
isConnected: true,
|
isConnected: true,
|
||||||
isEnabledOnPage: true,
|
isEnabledOnPage: true,
|
||||||
|
@ -66,7 +68,8 @@ export default class PopupPage extends Component {
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
targetLang: targetLang,
|
targetLang: targetLang,
|
||||||
langHistory: langHistory
|
langHistory: langHistory,
|
||||||
|
langList: generateLangOptions(getSettings("translationApi"))
|
||||||
});
|
});
|
||||||
|
|
||||||
const tabInfo = await getTabInfo();
|
const tabInfo = await getTabInfo();
|
||||||
|
@ -128,9 +131,10 @@ export default class PopupPage extends Component {
|
||||||
if (defaultTargetLang === secondLang) return;
|
if (defaultTargetLang === secondLang) return;
|
||||||
|
|
||||||
const equalsSourceAndTarget =
|
const equalsSourceAndTarget =
|
||||||
result.sourceLanguage === this.state.targetLang && result.percentage > 0;
|
result.sourceLanguage.split("-")[0] === this.state.targetLang.split("-")[0] && result.percentage > 0;
|
||||||
const equalsSourceAndDefault =
|
const equalsSourceAndDefault =
|
||||||
result.sourceLanguage === defaultTargetLang && result.percentage > 0;
|
result.sourceLanguage.split("-")[0] === defaultTargetLang.split("-")[0] && result.percentage > 0;
|
||||||
|
// split("-")[0] : deepLでenとen-USを区別しないために必要
|
||||||
|
|
||||||
if (!this.isSwitchedSecondLang) {
|
if (!this.isSwitchedSecondLang) {
|
||||||
if (equalsSourceAndTarget && equalsSourceAndDefault) {
|
if (equalsSourceAndTarget && equalsSourceAndDefault) {
|
||||||
|
@ -184,6 +188,7 @@ export default class PopupPage extends Component {
|
||||||
targetLang={this.state.targetLang}
|
targetLang={this.state.targetLang}
|
||||||
langHistory={this.state.langHistory}
|
langHistory={this.state.langHistory}
|
||||||
handleLangChange={this.handleLangChange}
|
handleLangChange={this.handleLangChange}
|
||||||
|
langList={this.state.langList}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import React from "react";
|
||||||
import browser from "webextension-polyfill";
|
import browser from "webextension-polyfill";
|
||||||
import generateLangOptions from "src/common/generateLangOptions";
|
import generateLangOptions from "src/common/generateLangOptions";
|
||||||
|
import { getSettings, setSettings } from "./settings";
|
||||||
|
|
||||||
const getDefaultLangs = () => {
|
const getDefaultLangs = () => {
|
||||||
const uiLang = browser.i18n.getUILanguage();
|
const uiLang = browser.i18n.getUILanguage();
|
||||||
|
@ -12,7 +14,31 @@ const getDefaultLangs = () => {
|
||||||
return { targetLang, secondTargetLang };
|
return { targetLang, secondTargetLang };
|
||||||
};
|
};
|
||||||
|
|
||||||
const langListOptions = generateLangOptions();
|
const updateLangsWhenChangeTranslationApi = () => {
|
||||||
|
const translationApi = getSettings("translationApi");
|
||||||
|
const targetLang = getSettings("targetLang");
|
||||||
|
const secondTargetLang = getSettings("secondTargetLang");;
|
||||||
|
const currentLangs = generateLangOptions(translationApi).map(option => option.value);
|
||||||
|
|
||||||
|
const mappingLang = lang => {
|
||||||
|
switch (lang) {
|
||||||
|
case "en": return "en-US";
|
||||||
|
case "en-US":
|
||||||
|
case "en-GB": return "en";
|
||||||
|
case "zh": return "zh-CN";
|
||||||
|
case "zh-CN":
|
||||||
|
case "zh-TW": return "zh";
|
||||||
|
case "pt": return "pt-PT";
|
||||||
|
case "pt-PT":
|
||||||
|
case "pt-BR": return "pt";
|
||||||
|
default: return currentLangs[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!currentLangs.includes(targetLang)) setSettings("targetLang", mappingLang(targetLang));
|
||||||
|
if (!currentLangs.includes(secondTargetLang)) setSettings("secondTargetLang", mappingLang(secondTargetLang));
|
||||||
|
};
|
||||||
|
|
||||||
const defaultLangs = getDefaultLangs();
|
const defaultLangs = getDefaultLangs();
|
||||||
const getTheme = () =>
|
const getTheme = () =>
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light";
|
window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light";
|
||||||
|
@ -21,13 +47,77 @@ export default [
|
||||||
{
|
{
|
||||||
category: "generalLabel",
|
category: "generalLabel",
|
||||||
elements: [
|
elements: [
|
||||||
|
{
|
||||||
|
id: "translationApi",
|
||||||
|
title: "translationApiLabel",
|
||||||
|
captions: [],
|
||||||
|
type: "none",
|
||||||
|
default: "google",
|
||||||
|
new: true,
|
||||||
|
childElements: [
|
||||||
|
{
|
||||||
|
id: "translationApi",
|
||||||
|
title: "googleApiLabel",
|
||||||
|
captions: ["googleApiCaptionLabel"],
|
||||||
|
type: "radio",
|
||||||
|
value: "google",
|
||||||
|
handleChange: () => updateLangsWhenChangeTranslationApi()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "translationApi",
|
||||||
|
title: "deeplApiLabel",
|
||||||
|
captions: ["deeplApiCaptionLabel"],
|
||||||
|
extraCaption:
|
||||||
|
React.createElement("p",
|
||||||
|
{ className: "caption" },
|
||||||
|
React.createElement("a",
|
||||||
|
{
|
||||||
|
href: "https://github.com/sienori/simple-translate/wiki/How-to-register-DeepL-API",
|
||||||
|
target: "_blank"
|
||||||
|
},
|
||||||
|
browser.i18n.getMessage("howToUseDeeplLabel"))
|
||||||
|
),
|
||||||
|
type: "radio",
|
||||||
|
value: "deepl",
|
||||||
|
handleChange: () => updateLangsWhenChangeTranslationApi()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "deeplPlan",
|
||||||
|
title: "deeplPlanLabel",
|
||||||
|
captions: ["deeplPlanCaptionLabel"],
|
||||||
|
type: "select",
|
||||||
|
default: "deeplFree",
|
||||||
|
shouldShow: () => (getSettings("translationApi") === "deepl"),
|
||||||
|
hr: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "deeplFreeLabel",
|
||||||
|
value: "deeplFree"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deeplProLabel",
|
||||||
|
value: "deeplPro"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "deeplAuthKey",
|
||||||
|
title: "deeplAuthKeyLabel",
|
||||||
|
captions: ["deeplAuthKeyCaptionLabel"],
|
||||||
|
type: "text",
|
||||||
|
default: "",
|
||||||
|
placeholder: "00000000-0000-0000-0000-00000000000000:fx",
|
||||||
|
shouldShow: () => (getSettings("translationApi") === "deepl"),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "targetLang",
|
id: "targetLang",
|
||||||
title: "targetLangLabel",
|
title: "targetLangLabel",
|
||||||
captions: ["targetLangCaptionLabel"],
|
captions: ["targetLangCaptionLabel"],
|
||||||
type: "select",
|
type: "select",
|
||||||
default: defaultLangs.targetLang,
|
default: defaultLangs.targetLang,
|
||||||
options: langListOptions,
|
options: () => generateLangOptions(getSettings("translationApi")),
|
||||||
useRawOptionName: true
|
useRawOptionName: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -36,7 +126,7 @@ export default [
|
||||||
captions: ["secondTargetLangCaptionLabel"],
|
captions: ["secondTargetLangCaptionLabel"],
|
||||||
type: "select",
|
type: "select",
|
||||||
default: defaultLangs.secondTargetLang,
|
default: defaultLangs.secondTargetLang,
|
||||||
options: langListOptions,
|
options: () => generateLangOptions(getSettings("translationApi")),
|
||||||
useRawOptionName: true
|
useRawOptionName: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -44,7 +134,8 @@ export default [
|
||||||
title: "ifShowCandidateLabel",
|
title: "ifShowCandidateLabel",
|
||||||
captions: ["ifShowCandidateCaptionLabel"],
|
captions: ["ifShowCandidateCaptionLabel"],
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
default: true
|
default: true,
|
||||||
|
shouldShow: () => (getSettings("translationApi") === "google")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue