Skip to content

Commit

Permalink
Imporve response speed by asynchronize EmojiTrans API; Add more clipb…
Browse files Browse the repository at this point in the history
…oard options
  • Loading branch information
Hydrapse committed Jul 19, 2022
1 parent 17a0af7 commit fb86d37
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 65 deletions.
2 changes: 2 additions & 0 deletions extensions/dlmoji/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

![Config Panel](./assets/Config-Panel.png)

Some APIs might cause timeout errors and be unstable. To avoid these annoying alerts, you can uncheck the corresponding APIs in the following Configuration.

To enable `Emotion Analysis`, you need to deploy deepmoji as a web service on your server. Here we offer an off-the-shelf [deepmoji docker image](https://hub.docker.com/r/thandaanda/deepmoji). If you want to use another model service, remember to follow the response format:

```json
Expand Down
Binary file modified extensions/dlmoji/assets/Config-Panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 18 additions & 8 deletions extensions/dlmoji/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions extensions/dlmoji/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
"preferences": [
{
"title": "API Selection",
"name": "useEmojiTranslate",
"type": "checkbox",
"label": "Emoji Translate",
"required": false,
"default": true,
"description": "Translate human language to emoji"
},
{
"name": "useVerbatimTranslate",
"type": "checkbox",
"label": "18dao Verbatim Chinese Translate",
Expand Down Expand Up @@ -78,10 +86,12 @@
"cheerio": "^1.0.0-rc.12",
"crypto-js": "^4.1.1",
"form-data": "^4.0.0",
"lodash": "^4.17.21",
"prettier": "^2.7.1"
},
"devDependencies": {
"@types/crypto-js": "^4.1.1",
"@types/lodash": "^4.14.182",
"@types/node": "~16.10.0",
"@types/react": "^17.0.28",
"@typescript-eslint/eslint-plugin": "^5.0.0",
Expand Down
30 changes: 20 additions & 10 deletions extensions/dlmoji/src/TranslateResult.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { Component, Fragment } from "react"
import { SECTION_TYPE } from "./consts"
import { Action, ActionPanel, Clipboard, Color, Icon, List, getPreferenceValues } from "@raycast/api"
import { truncate } from "./utils"
import { COPY_SEPARATOR, SECTION_TYPE } from "./consts"
import {
Action,
ActionPanel,
Clipboard,
Color,
Icon,
List,
getPreferenceValues,
KeyEquivalent,
Keyboard,
} from "@raycast/api"
import { clamp, truncate } from "./utils"

interface ITranslateResult {
inputState?: string
Expand All @@ -19,7 +29,7 @@ function reformatCopyTextArray(data: string[], limitResultAmount = 10): IReforma
return finalData.map((text, idx) => {
return {
// title: finalData.length - 1 === idx && idx > 0 ? "All" : truncate(text),
title: idx === 0 ? "All" : truncate(text),
title: idx === dataLength ? "All" : truncate(text, 40),
value: text,
}
})
Expand All @@ -32,9 +42,9 @@ function ActionCopyListSection(props: IActionCopyListSection) {
return null
}

const SEPARATOR = "; "
const copyTextArray = props.copyText.split(SEPARATOR)
copyTextArray.length > 1 && copyTextArray.unshift(props.copyText)
const copyTextArray = props.copyText.split(COPY_SEPARATOR)
const newCopyText = copyTextArray.join(" ")
copyTextArray.length > 1 && copyTextArray.push(newCopyText)
const finalTextArray = reformatCopyTextArray(copyTextArray, 6)

// const shortcutKeyEquivalent: Keyboard.KeyEquivalent[] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
Expand Down Expand Up @@ -67,10 +77,11 @@ function ActionCopyListSection(props: IActionCopyListSection) {
{finalTextArray.map((textItem, key) => {
const title = textItem.title
const value = textItem.value
const shortcutKey = clamp(key + 1).toString() as Keyboard.KeyEquivalent
return (
<Action.CopyToClipboard
onCopy={() => preferences.isAutomaticPaste && Clipboard.paste(textItem.value)}
// shortcut={{ modifiers: ["cmd"], key: [key] }}
shortcut={{ modifiers: ["cmd"], key: shortcutKey }}
title={`Copy ${title}`}
content={value}
key={key}
Expand Down Expand Up @@ -125,12 +136,11 @@ export default function TranslateResult(props: ITranslateResult) {
icon={iconMaps[result.type!]}
title={item.title}
subtitle={item?.subtitle}
accessoryTitle={item.phonetic}
detail={<List.Item.Detail markdown={item.title} />}
actions={
<ListActionPanel
queryText={props.inputState}
copyText={item?.key || item.subtitle || item.title}
copyText={item?.copyText || item.key || item.subtitle}
/>
}
/>
Expand Down
35 changes: 30 additions & 5 deletions extensions/dlmoji/src/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import axios from "axios"
import querystring from "node:querystring"
import CryptoJS from "crypto-js"
import { checkURL, defaultBaiduAppId, defaultBaiduAppSecret, preferences, showErrorToast } from "./utils"
import { getEmojiTransKey } from "./storage"

// baidu app id and secret
const baiduAppId = preferences.baiduAppId.trim().length > 0 ? preferences.baiduAppId.trim() : defaultBaiduAppId
Expand All @@ -15,6 +16,31 @@ if (deepmojiURL.length > 0 && !checkURL(deepmojiURL)) {
showErrorToast("deepmoji", "invalid URL address")
}

export async function preConnect() {
const connects = []
if (preferences.useEmojiTranslate) {
connects.push(
getEmojiTransKey(false).then((key) => {
fetchEmojiTrans("", "en", key)
})
)
}
if (preferences.useVerbatimTranslate) {
connects.push(fetchChineseEmojiTrans(""))
}
if (preferences.useEmojiAll) {
connects.push(fetchEmojiAll("", "en"))
}
return axios.all(connects)
}

export function setAxiosTimeout(seconds = 6) {
axios.interceptors.request.use((config) => {
config.timeout = seconds * 1000
return config
})
}

/**
* 百度翻译API
* Docs: https://fanyi-api.baidu.com/doc/21
Expand All @@ -35,7 +61,10 @@ export async function fetchBaiduTrans(queryText: string): Promise<any> {
salt: salt,
sign: sign,
}
return axios.get(url, { params })
return axios.get(url, { params }).catch((err) => {
showErrorToast("Baidu Translate", err.message)
return
})
}

export async function fetchDeepl(queryText: string): Promise<any> {
Expand Down Expand Up @@ -98,12 +127,8 @@ export async function fetchEmojiAll(queryText: string, fromLanguage: string): Pr
lang: lang,
}),
{
timeout: 6 * 1000,
headers: {
// 'User-Agent': 'apifox/1.0.0 (https://www.apifox.cn)',
// 'Accept': '*/*',
// 'Content-Type': 'multipart/form-data',
// 'Connection': 'keep-alive',
referer: "https://www.emojiall.com/",
},
}
Expand Down
2 changes: 2 additions & 0 deletions extensions/dlmoji/src/consts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export enum SECTION_TYPE {
Emoji = "Related Emojis",
Phrase = "Phrases",
}

export const COPY_SEPARATOR = "; "
69 changes: 53 additions & 16 deletions extensions/dlmoji/src/dlmoji.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ import { useEffect, useState } from "react"
import TranslateResult from "./TranslateResult"
import { Icon, List } from "@raycast/api"
import axios from "axios"
import { fetchBaiduTrans, fetchChineseEmojiTrans, fetchDeepmoji, fetchEmojiAll, fetchEmojiTrans } from "./api"
import { cloneDeep } from "lodash"
import {
fetchBaiduTrans,
fetchChineseEmojiTrans,
fetchDeepmoji,
fetchEmojiAll,
fetchEmojiTrans,
preConnect,
setAxiosTimeout,
} from "./api"
import {
formatBaiduTrans,
formatChineseEmojiTrans,
Expand All @@ -14,9 +23,14 @@ import {
import { getEmojiTransKey } from "./storage"
import { SECTION_TYPE } from "./consts"

// use preConnect to reduce API response time
preConnect()
setTimeout(() => {
setAxiosTimeout(6)
}, 8000)

let delayFetchTranslateAPITimer: NodeJS.Timeout
let delayUpdateTargetLanguageTimer: NodeJS.Timeout
// let othersLoaded = false

export default function () {
const [inputState, updateInputState] = useState<string>()
Expand All @@ -28,8 +42,8 @@ export default function () {

// String Filter
const queryGlobal: string = inputState
const queryText: string = queryGlobal.replace(/伶仔|伶伶/g, "公主").replace(/邓港大/g, "猪")
const queryEmoji: string = queryGlobal.replace(/伶仔|伶伶/g, "🐰").replace(/邓港大/g, "🦊")
const queryText: string = queryGlobal.replace(/陈炤伶|伶仔|伶伶/g, "公主").replace(/邓港大/g, "猪")
const queryEmoji: string = queryGlobal.replace(/陈炤伶|伶仔|伶伶/g, "🐰").replace(/邓港大/g, "🦊")

const hasChinese = /[\u4E00-\u9FA5]+/g.test(queryText)
const lang = hasChinese ? "zh" : "en"
Expand All @@ -49,46 +63,69 @@ export default function () {
}
const res = await fetchDeepmoji(enText)
if (!res?.data) return
console.log("Deepmoji Data Received")
return formatDeepmoji(res.data.emoji[0])
}
async function getEmojiTrans(updateKey = false): Promise<ITranslateReformatResultItem | undefined> {
if (!preferences.useEmojiTranslate) return
const key = await getEmojiTransKey(updateKey)
const res = await fetchEmojiTrans(queryEmoji, lang, key)
if (!res?.data) {
if (!res) return
if (!res.data) {
console.log("Emoji Translation Key Update")
return getEmojiTrans(true)
}
console.log("EmojiTrans Data Received")
return formatEmojiTrans(res.data)
}
async function getChineseEmojiTrans(): Promise<ITranslateReformatResultItem | undefined> {
if (!preferences.useVerbatimTranslate || !hasChinese) return
const res = await fetchChineseEmojiTrans(queryEmoji)
if (!res?.data) return
console.log("ChineseEmojiTrans Data Received")
return formatChineseEmojiTrans(res.data)
}
async function getEmojiAll(): Promise<any> {
if (!preferences.useEmojiAll) return
const res = await fetchEmojiAll(queryText, lang)
if (!res?.data) return
console.log("EmojiAll Data Received")
return formatEmojiAll(res.data)
}

axios.all([getDeepmoji(), getEmojiTrans(), getChineseEmojiTrans(), getEmojiAll()]).then(
axios.spread((deepmoji, emojiTrans, verbatimTrans, emojiAll) => {
const result: ITranslateReformatResult = {
getEmojiTrans().then((emojiTrans) => {
if (!emojiTrans) return
if (dataList[0]?.type === SECTION_TYPE.Translate) {
dataList[0].children.unshift(emojiTrans)
} else {
dataList.unshift({
type: SECTION_TYPE.Translate,
title: SECTION_TYPE.Translate,
children: [],
}
if (emojiTrans) {
result.children.push(emojiTrans)
}
children: [emojiTrans],
})
}
updateTranslateResultState(cloneDeep(dataList))
})

axios.all([getDeepmoji(), getChineseEmojiTrans(), getEmojiAll()]).then(
axios.spread((deepmoji, verbatimTrans, emojiAll) => {
const transArray: ITranslateReformatResultItem[] = []
if (deepmoji) {
result.children.push(deepmoji)
transArray.push(deepmoji)
}
if (verbatimTrans) {
result.children.push(verbatimTrans)
transArray.push(verbatimTrans)
}

if (dataList[0]?.type === SECTION_TYPE.Translate) {
dataList[0].children.push(...transArray)
} else {
dataList.unshift({
type: SECTION_TYPE.Translate,
title: SECTION_TYPE.Translate,
children: transArray,
})
}
dataList.unshift(result)

if (emojiAll?.length > 0) {
dataList.push(...emojiAll)
Expand Down
Loading

0 comments on commit fb86d37

Please sign in to comment.